diff --git a/B-24302 UV Case Type Family Updates.linq b/B-24302 UV Case Type Family Updates.linq new file mode 100644 index 0000000..27526f0 --- /dev/null +++ b/B-24302 UV Case Type Family Updates.linq @@ -0,0 +1,566 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var data = @"CaseTypeFamily Name SkipICD ICD10Code MSDRGCode +M-420 1 Cervical Level Anterior Approach FALSE 0RG0070 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0370 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0470 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1070 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1370 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1470 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4070 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4370 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43K0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4470 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44A0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44J0 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44K0 471 +M-421 1 Cervical Level Open Approach FALSE XRG0092 471 +M-421 1 Cervical Level Open Approach FALSE XRG00F3 471 +M-421 1 Cervical Level Open Approach FALSE XRG1092 471 +M-421 1 Cervical Level Open Approach FALSE XRG10F3 471 +M-421 1 Cervical Level Open Approach FALSE XRG4092 471 +M-421 1 Cervical Level Open Approach FALSE XRG40F3 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0071 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG007J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0371 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG037J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0471 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG047J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1071 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG107J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1371 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG137J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1471 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG147J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4071 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG407J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4371 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG437J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43KJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4471 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG447J 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44AJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44J1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44JJ 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44K1 471 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44KJ 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2070 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20A0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20J0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20K0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2370 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23A0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23J0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23K0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2470 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24A0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24J0 471 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24K0 471 +M-424 2+ Cervical Level Open Approach FALSE XRG2092 471 +M-424 2+ Cervical Level Open Approach FALSE XRG20F3 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2071 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG207J 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20AJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20J1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20JJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20K1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20KJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2371 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG237J 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23AJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23J1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23JJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23K1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23KJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2471 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG247J 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24AJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24J1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24JJ 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24K1 471 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24KJ 471 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0070 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0370 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0470 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1070 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1370 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1470 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4070 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4370 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43K0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4470 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44A0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44J0 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44K0 472 +M-421 1 Cervical Level Open Approach FALSE XRG0092 472 +M-421 1 Cervical Level Open Approach FALSE XRG00F3 472 +M-421 1 Cervical Level Open Approach FALSE XRG1092 472 +M-421 1 Cervical Level Open Approach FALSE XRG10F3 472 +M-421 1 Cervical Level Open Approach FALSE XRG4092 472 +M-421 1 Cervical Level Open Approach FALSE XRG40F3 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0071 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG007J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0371 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG037J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0471 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG047J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1071 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG107J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1371 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG137J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1471 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG147J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4071 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG407J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4371 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG437J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43KJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4471 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG447J 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44AJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44J1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44JJ 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44K1 472 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44KJ 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2070 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20A0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20J0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20K0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2370 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23A0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23J0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23K0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2470 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24A0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24J0 472 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24K0 472 +M-424 2+ Cervical Level Open Approach FALSE XRG2092 472 +M-424 2+ Cervical Level Open Approach FALSE XRG20F3 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2071 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG207J 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20AJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20J1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20JJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20K1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20KJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2371 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG237J 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23AJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23J1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23JJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23K1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23KJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2471 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG247J 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24AJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24J1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24JJ 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24K1 472 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24KJ 472 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0070 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG00K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0370 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG03K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG0470 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG04K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1070 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG10K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1370 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG13K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG1470 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG14K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4070 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG40K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4370 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG43K0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG4470 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44A0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44J0 473 +M-420 1 Cervical Level Anterior Approach FALSE 0RG44K0 473 +M-421 1 Cervical Level Open Approach FALSE XRG0092 473 +M-421 1 Cervical Level Open Approach FALSE XRG00F3 473 +M-421 1 Cervical Level Open Approach FALSE XRG1092 473 +M-421 1 Cervical Level Open Approach FALSE XRG10F3 473 +M-421 1 Cervical Level Open Approach FALSE XRG4092 473 +M-421 1 Cervical Level Open Approach FALSE XRG40F3 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0071 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG007J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG00KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0371 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG037J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG03KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG0471 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG047J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG04KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1071 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG107J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG10KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1371 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG137J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG13KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG1471 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG147J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG14KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4071 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG407J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG40KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4371 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG437J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG43KJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG4471 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG447J 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44AJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44J1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44JJ 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44K1 473 +M-422 1 Cervical Level Posterior Approach FALSE 0RG44KJ 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2070 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20A0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20J0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG20K0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2370 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23A0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23J0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG23K0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG2470 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24A0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24J0 473 +M-423 2+ Cervical Level Anterior Approach FALSE 0RG24K0 473 +M-424 2+ Cervical Level Open Approach FALSE XRG2092 473 +M-424 2+ Cervical Level Open Approach FALSE XRG20F3 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2071 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG207J 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20AJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20J1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20JJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20K1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG20KJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2371 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG237J 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23AJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23J1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23JJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23K1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG23KJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG2471 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG247J 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24AJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24J1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24JJ 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24K1 473 +M-425 2+ Cervical Level Posterior Approach FALSE 0RG24KJ 473"; + + var rows = data.Split("\n".ToCharArray()) + .Skip(1) + .ToList() + .ConvertAll(d => new NewCaseTypeFamilyMapping(d.Trim("\r".ToCharArray()).Split('\t'))) + .GroupBy(d => d.CaseTypeFamily, (key, info) => new + { + CaseTypeFamily = key, + data = info.ToList(), + sql = info.Aggregate(new StringBuilder($@" +SELECT @CaseTypeFamilyID = ctf.CaseTypeFamilyID +FROM dss.CaseTypeFamily AS ctf +WHERE ctf.CaseTypeFamilyGlobalID = '{key}' + +INSERT INTO dss.CaseTypeFamilyMappingICD10 ( CaseTypeFamilyID, SkipICD, ICD10Code, MSDRGCode, CaseTypeFamilyVersionID ) +VALUES +"), + (x, y) => x.AppendLine(y.ToString())).ToString().TrimEnd(new[] { '\r', '\n', ',' }), + rollback = $@"DELETE FROM dss.CaseTypeFamilyMappingICD10 +WHERE EXISTS(SELECT 1 FROM dss.CaseTypeFamily AS ctf + WHERE ctf.CaseTypeFamilyGlobalID = '{key}' and CaseTypeFamilyMappingICD10.CaseTypeFamilyID = ctf.CaseTypeFamilyID AND CaseTypeFamilyVersionID = 1) +DELETE FROM dss.CaseTypeFamily WHERE CaseTypeFamilyGlobalID = '{key}' +" + }); + var sqlScript = $@"--Author: tlamb +--Version: 2019.42 +--Forward +DELETE +FROM dss.CaseTypeFamilyMappingICD10 +WHERE EXISTS(SELECT 1 +FROM dss.CaseTypeFamily AS ctf +WHERE ctf.CaseTypeFamilyID = CaseTypeFamilyMappingICD10.CaseTypeFamilyID AND ctf.CaseTypeFamilyGlobalID = 'M-61') +AND CaseTypeFamilyMappingICD10.MSDRGCode IN('471','472','473') +AND CaseTypeFamilyMappingICD10.SkipICD = 1 +AND CaseTypeFamilyMappingICD10.CaseTypeFamilyVersionID = 1 + +INSERT INTO dss.CaseTypeFamily(CaseTypeFamilyGUID, Name, CaseTypeFamilyGlobalID) +VALUES(NEWID(), '1 Cervical Level Anterior Approach', 'M-420'), +(NEWID(), '1 Cervical Level Open Approach', 'M-421'), +(NEWID(), '1 Cervical Level Posterior Approach', 'M-422'), +(NEWID(), '2+ Cervical Level Anterior Approach', 'M-423'), +(NEWID(), '2+ Cervical Level Open Approach', 'M-424'), +(NEWID(), '2+ Cervical Level Posterior Approach', 'M-425') + +DECLARE @CaseTypeFamilyID INT + +{string.Join("\r\n", rows.Select(r => r.sql))} +--Rollback +{string.Join("\r\n", rows.Select(r => r.rollback))}"; + + sqlScript.Dump("script"); + File.WriteAllText(@"D:\git\2019-10-01-11-14 B-24302 UV Case Type Family Updates.sql", sqlScript); + rows.Dump(); + + // var sql = rows.Aggregate(new StringBuilder("DECLARE @CaseTypeFamilyID INT"), + // (x, y) => x.AppendLine( + // data.Aggregate(new StringBuilder($"SELECT @CaseTypeFamilyID = ctf.CaseTypeFamilyID FROM dss.CaseTypeFamily AS ctf WHERE ctf.CaseTypeFamilyGlobalID = '{y.CaseTypeFamily}'"), + // (a, b) => a.AppendLine(b.ToString())).ToString())).ToString(); + // sql.Dump(); +} + +// Define other methods and classes here + +public class NewCaseTypeFamilyMapping +{ + public string CaseTypeFamily { get; set; } + public string Name { get; set; } + internal bool bSkipICD { get; set; } + public int SkipICD => bSkipICD ? 1 : 0; + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + + public NewCaseTypeFamilyMapping(string[] data) + { + if (data.Length != 5) + throw new ArgumentException(nameof(data)); + CaseTypeFamily = data[0]; + Name = data[1]; + bSkipICD = bool.Parse(data[2]); + ICD10Code = data[3]; + MSDRGCode = data[4]; + } + + public override string ToString() + { + //return $"\t(@CaseTypeFamilyID, '{Name}', {SkipICD}, '{ICD10Code}', '{MSDRGCode}', 1),"; + return $"\t(@CaseTypeFamilyID, {SkipICD}, '{ICD10Code}', '{MSDRGCode}', 1),"; + } +} \ No newline at end of file diff --git a/CCI Timings.linq b/CCI Timings.linq new file mode 100644 index 0000000..1a30f72 --- /dev/null +++ b/CCI Timings.linq @@ -0,0 +1,220 @@ + + + 4f885e7e-d8bb-427c-a54e-8e3e1c3137a7 + true + IOAK-SQL-LOG-01.sdt.local + jazz log prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +public static string PrimaryUrl => "Opportunities.aspx"; +public static string UrlGroup => "/CCI"; +public static DateTime cutoff { get; set; } = DateTime.Now.AddDays((((int)DateTime.Now.DayOfWeek) * -1) + 1).Date; + +void Main() +{ + RunTimings(); +} + +public void RunTimings() +{ + cutoff = DateTime.Now.AddDays(-30); + var timings = GetTimings(cutoff) + .Where(t => t.Key.Group == 0 && t.Data.Any()); + + var outliers = timings.SelectMany(t => t.Data.Where(d => d.ClientTimeData / 1000.0d > 4.0d)); + outliers.Dump(nameof(outliers)); + + timings + .OrderByDescending(t => t.Key.ClientTimeMax > 4 ? t.Key.ClientTimeMax : 0) + .ThenBy(t => t.Key.Group) + .ThenBy(t => t.Key.Url.Contains(PrimaryUrl) ? "!" : t.Key.Url) + .ThenBy(t => t.Key.Application) + .ThenByDescending(t => t.Key.Date) + .ThenBy(t => t.Key.Browser.StartsWith("IE") ? 0 : 1) + .Dump(); +} + +public IEnumerable GetTimings(DateTime cutoff) +{ + return from log in Archive_PageLogs + where (log.Url.StartsWith(UrlGroup)) + && log.DateTimeStamp > cutoff + group log by new { Group = (log.UserName.StartsWith("sdt\\") ? 1 : 0), log.Url, log.Browser, Date = log.DateTimeStamp.Value.Date, log.Application } into grp + //join dbs in ViewActiveDatabases on grp.FirstOrDefault().DatabaseGuid equals dbs.DatabaseGUID + orderby grp.Key.Group, (grp.FirstOrDefault().ClientTime / 1000) descending, grp.Key.Date descending + select new MetricData + { + Key = new MetricKey + { + Application = grp.Key.Application, + Group = grp.Key.Group, + Url = grp.Key.Url, + Browser = grp.Key.Browser, + Date = grp.Key.Date, + ClientTimeAvg = grp.ToList().Average(g => (g.ClientTime / 1000.0d)) ?? 0.0d, + ClientTimeMin = grp.ToList().Min(g1 => (g1.ClientTime / 1000.0d)) ?? 0.0d, + ClientTimeMax = grp.ToList().Max(g1 => (g1.ClientTime / 1000.0d)) ?? 0.0d, + Count = grp.ToList().Count + }, + Data = grp + .Select(g => new Metric(g.DatabaseGuid.Value, ViewActiveDatabases) + { + UrlParams = g.UrlParams, + UserName = g.UserName, + WebServer = g.WebServer, + ServerTimeData = g.ServerTime ?? 0, + ClientTimeData = g.ClientTime ?? 0, + DatabaseName = g.DatabaseName, + ClientTime = g.ClientTime ?? 0 / 1000.0d, + ClientTimeAvg = grp.ToList().Average(g1 => g1.ClientTime ?? 0.0d / 1000.0d), + ClientTimeMin = grp.ToList().Min(g1 => g1.ClientTime ?? 0.0d / 1000.0d), + ClientTimeMax = grp.ToList().Max(g1 => g1.ClientTime ?? 0.0d / 1000.0d) + }).Where(x => (x.ClientTimeData / 1000.0d) > x.ClientTimeAvg || ((x.ClientTimeData / 1000.0d) > 4.0d)) + }; +} + +// Define other methods and classes here + +public class Metric +{ + public double ClientTime { get; set; } + public double ClientTimeData { get; set; } + public double ClientTimeAvg { get; set; } + public double ClientTimeMin { get; set; } + public double ClientTimeMax { get; set; } + public string WebServer { get; set; } + public string PhysicalName { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string UserName { get; set; } + public string UrlParams { get; set; } + public int ServerTimeData { get; set; } + public string OrgPin { get; set; } + + public Metric() + { + + } + + public Metric(Guid databaseGuid, Table activeDatabases) + { + DatabaseGuid = databaseGuid; + var activeDatabase = activeDatabases.SingleOrDefault(vad => vad.DatabaseGUID == databaseGuid); + PhysicalName = activeDatabase?.PhysicalName ?? string.Empty; + OrgPin = activeDatabase?.OrgPin ?? string.Empty; + } + + object ToDump() => new + { + ClientTimeMax = new XElement("LINQPad.HTML", + new XElement("div", + new XAttribute("align", "right"), + new XAttribute("style", $"background-color:{(ClientTimeMax > 4.0d ? "red" : (ClientTimeAvg < (ClientTimeData / 1000.0d)) ? "violet" : "white")};"), + $"{ClientTimeMax:n}".PadLeft(10))), + ClientTimeAvg, + ClientTimeMin, + WebServer, + OrgPin, + DatabaseName, + PhysicalName, + UserName, + UrlParams, + ServerTime = $"{ServerTimeData:n0}".PadLeft(10) + }; +} + +public class MetricKey +{ + public string Application { get; set; } + public int Group { get; set; } + public string Browser { get; set; } + public string Url { get; set; } + //public int UrlLength { get; set; } + public DateTime Date { get; set; } + public double ClientTimeAvg { get; set; } + public double ClientTimeMin { get; set; } + public double ClientTimeMax { get; set; } + public int Count { get; set; } + + object ToDump() => new + { + Application, + GroupName = Group == 0 ? "Clients" : "Strata", + Browser, + URL = Url, //.PadRight(UrlLength), + OnDate = Date.ToShortDateString(), + Avg_ClientTime = $"{ClientTimeAvg:N2}", + Min_ClientTime = $"{ClientTimeMin:N2}", + Max_ClientTime = $"{ClientTimeMax:N2}", + Count + }; +} + +public class MetricData +{ + public MetricKey Key { get; set; } + public IEnumerable Data { get; set; } + + object ToDump() => new + { + Group = Key, + Statistics = Data + .OrderBy(d => d.WebServer) + .ThenBy(d => d.DatabaseName) + .ThenBy(d => d.UserName) + .ThenBy(d => d.ClientTimeData) + }; +} \ No newline at end of file diff --git a/CI Testing Stuff/Payroll Opportunity Metric.linq b/CI Testing Stuff/Payroll Opportunity Metric.linq new file mode 100644 index 0000000..def8ffb --- /dev/null +++ b/CI Testing Stuff/Payroll Opportunity Metric.linq @@ -0,0 +1,79 @@ + + +void Main() +{ + var pom = new PayrollOpportunityMetric + { + BaselineMonth01Dollars = 1.0m, + ActualMonth03Dollars = 1.0m, + CommittedMonth06Dollars = 1.0m + }; + pom.BaselineDollars().Dump(); + pom.ActualDollars().Dump(); + pom.CommittedDollars().Dump(); +} + +// Define other methods and classes here + +public class PayrollOpportunityMetric +{ + public decimal BaselineMonth01Dollars { get; set; } = 0.0m; + public decimal BaselineMonth02Dollars { get; set; } = 0.0m; + public decimal BaselineMonth03Dollars { get; set; } = 0.0m; + public decimal BaselineMonth04Dollars { get; set; } = 0.0m; + public decimal BaselineMonth05Dollars { get; set; } = 0.0m; + public decimal BaselineMonth06Dollars { get; set; } = 0.0m; + public decimal BaselineMonth07Dollars { get; set; } = 0.0m; + public decimal BaselineMonth08Dollars { get; set; } = 0.0m; + public decimal BaselineMonth09Dollars { get; set; } = 0.0m; + public decimal BaselineMonth10Dollars { get; set; } = 0.0m; + public decimal BaselineMonth11Dollars { get; set; } = 0.0m; + public decimal BaselineMonth12Dollars { get; set; } = 0.0m; + + public decimal ActualMonth01Dollars { get; set; } = 0.0m; + public decimal ActualMonth02Dollars { get; set; } = 0.0m; + public decimal ActualMonth03Dollars { get; set; } = 0.0m; + public decimal ActualMonth04Dollars { get; set; } = 0.0m; + public decimal ActualMonth05Dollars { get; set; } = 0.0m; + public decimal ActualMonth06Dollars { get; set; } = 0.0m; + public decimal ActualMonth07Dollars { get; set; } = 0.0m; + public decimal ActualMonth08Dollars { get; set; } = 0.0m; + public decimal ActualMonth09Dollars { get; set; } = 0.0m; + public decimal ActualMonth10Dollars { get; set; } = 0.0m; + public decimal ActualMonth11Dollars { get; set; } = 0.0m; + public decimal ActualMonth12Dollars { get; set; } = 0.0m; + + public decimal CommittedMonth01Dollars { get; set; } = 0.0m; + public decimal CommittedMonth02Dollars { get; set; } = 0.0m; + public decimal CommittedMonth03Dollars { get; set; } = 0.0m; + public decimal CommittedMonth04Dollars { get; set; } = 0.0m; + public decimal CommittedMonth05Dollars { get; set; } = 0.0m; + public decimal CommittedMonth06Dollars { get; set; } = 0.0m; + public decimal CommittedMonth07Dollars { get; set; } = 0.0m; + public decimal CommittedMonth08Dollars { get; set; } = 0.0m; + public decimal CommittedMonth09Dollars { get; set; } = 0.0m; + public decimal CommittedMonth10Dollars { get; set; } = 0.0m; + public decimal CommittedMonth11Dollars { get; set; } = 0.0m; + public decimal CommittedMonth12Dollars { get; set; } = 0.0m; +} + +public static class PayrollOpportunityMetricExtensions +{ + public static IEnumerable BaselineDollars(this PayrollOpportunityMetric pom) => + typeof(PayrollOpportunityMetric) + .GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.Name.StartsWith("BaselineMonth") && p.Name.EndsWith("Dollars")) + .Select(dp => (decimal) dp.GetValue(pom, null)); + + public static IEnumerable ActualDollars(this PayrollOpportunityMetric pom) => + typeof(PayrollOpportunityMetric) + .GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.Name.StartsWith("ActualMonth") && p.Name.EndsWith("Dollars")) + .Select(dp => (decimal)dp.GetValue(pom, null)); + + public static IEnumerable CommittedDollars(this PayrollOpportunityMetric pom) => + typeof(PayrollOpportunityMetric) + .GetProperties(BindingFlags.Instance | BindingFlags.Public) + .Where(p => p.Name.StartsWith("CommittedMonth") && p.Name.EndsWith("Dollars")) + .Select(dp => (decimal)dp.GetValue(pom, null)); +} \ No newline at end of file diff --git a/Calculate FactOpportunityMetrics YTD Rollups.linq b/Calculate FactOpportunityMetrics YTD Rollups.linq new file mode 100644 index 0000000..b49009b --- /dev/null +++ b/Calculate FactOpportunityMetrics YTD Rollups.linq @@ -0,0 +1,96 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + DimTimeClasses.Dump(); + + var factList = from fact in FactOpportunityMetrics.ToList() + join fm in DimFiscalMonths.ToList() on fact.FiscalMonthID equals fm.FiscalMonthID + join dtc in DimTimeClasses.ToList() on fact.TimeClassID equals dtc.TimeClassID + select new { fact, fm.SortOrder }; + + var updates = + (from f in factList //.Where(l => l.fact.TimeClassID != 5) + select new + { + f.fact, + AmountYTD = factList + .Where(l => l.fact.OpportunityGUID == f.fact.OpportunityGUID && l.fact.TimeClassID == f.fact.TimeClassID && l.fact.FiscalYearID == f.fact.FiscalYearID && l.SortOrder <= f.SortOrder) + .GroupBy(l => new { l.fact.OpportunityGUID, l.fact.TimeClassID, l.fact.FiscalYearID }) + .Select(l => l.Sum(x => x.fact.Amount)).Single() + }).Where(r => r.AmountYTD != 0).OrderBy(r => r.fact.RowID).ToList(); + + foreach (var update in updates) + { + FactOpportunityMetrics.Where(fom => update.RowID == fom.RowID).ToList() + .ForEach(fact => fact.AmountYTD = update.AmountYTD); + FactOpportunityMetrics.Where(fom => update.RowID == fom.RowID).Dump(); + } + + SubmitChanges(); + FactOpportunityMetrics.Where(fom => fom.AmountYTD != 0) + .Join(ViewOpportunity, f => f.OpportunityGUID, o => o.OpportunityGUID, + (f, o) => new { f.MetricName, f.TimeClassID, f.FiscalYearID, f.FiscalMonthID, f.Amount, f.AmountYTD, o.Name, o.OpportunityType }).Dump(); +} + + +// Define other methods and classes here \ No newline at end of file diff --git a/CaseType Analytics/CaseType Analysis.linq b/CaseType Analytics/CaseType Analysis.linq new file mode 100644 index 0000000..10fbc55 --- /dev/null +++ b/CaseType Analytics/CaseType Analysis.linq @@ -0,0 +1,193 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.ComponentModel + + +void Main() +{ + var caseTypes = (from fpes in FactPatientEncounterSummaries + join ves in VariationEncounterSavings on fpes.EncounterID equals ves.EncounterID + join vo in VariationOpportunities on ves.OpportunityGUID equals vo.OpportunityGUID + join config in Configurations on vo.ConfigurationGUID equals config.ConfigurationGUID + join cte in CaseTypeEntities on vo.CaseTypeEntityID equals cte.CaseTypeEntityID + join dct in DimCaseTypes on cte.CaseTypeGUID equals dct.MemberGUID + join d in DimMSDRGs on fpes.ReportingDRGID equals d.MSDRGID into da + from e in da.DefaultIfEmpty() + join f in DimAPRDRGs on fpes.APDRGID equals f.APRDRGID into fa + from g in fa.DefaultIfEmpty() + join cpt in DimCPTs on fpes.PrimaryCPTID equals cpt.CPTID into cpta + from ca in cpta.DefaultIfEmpty() + where config.FiscalYearID == 2020 + select new + { + vo.ConfigurationGUID, + config.FiscalYearID, + dct.CaseTypeId, + dct.Name, + CCMCCCategory = e.CCMCCCategory ?? "", + SOI = g.APRSOI ?? "", + ROM = g.APRROM ?? "", + CPTCode = ca.CPTCode ?? "", + CaseTypeConfig = JsonConvert.DeserializeObject(dct.CaseTypeConfigJSON) + }) + .Distinct() + .Select(t => new + { + t.ConfigurationGUID, + t.FiscalYearID, + t.CaseTypeId, + t.Name, + t.CCMCCCategory, + t.SOI, + t.ROM, + t.CPTCode, + t.CaseTypeConfig.AgeCohortIDInclusions, + t.CaseTypeConfig.PhysicianIDExclusions, + t.CaseTypeConfig.StandardDeviationExcludedTypeEnum, + t.CaseTypeConfig.LengthOfStayThreshold, + t.CaseTypeConfig.SOIROMInclusions, + t.CaseTypeConfig.CCMCCCategories, + t.CaseTypeConfig.CPTCodes, + t.CaseTypeConfig.PatientTypeRollupIDInclusions, + t.CaseTypeConfig.PhysicianMinVolume + }) + .OrderBy(t => t.Name); + caseTypes.Dump(); +} + +// Define other methods and classes here +public const string CCMCCCATEGORY_CC = "CC"; +public const string CCMCCCATEGORY_MCC = "MCC"; +public const string CCMCCCATEGORY_WO = "W/O"; +public const string CCMCCCATEGORY_NA = "N/A"; +public const string CCMCCCATEGORY_CCMCC = "CC/MCC"; + + +public enum CCMCCCategoryTypes +{ + /// + /// No Category + /// + [Description("")] + None, + /// + /// Complication or Comorbidity + /// + [Description(CCMCCCATEGORY_CC)] + CC, + /// + /// Major Complication or Comorbidity + /// + [Description(CCMCCCATEGORY_MCC)] + MCC, + /// + /// Without Complication or Comorbidity OR Major Complication or Comorbidity + /// + [Description(CCMCCCATEGORY_WO)] + WO, + /// + /// Not Available + /// + [Description(CCMCCCATEGORY_NA)] + NA, + /// + /// Both Complication or Comorbidity AND Major Complication or Comorbidity + /// + [Description(CCMCCCATEGORY_CCMCC)] + CCMCC +} + +public class SOIROMInclusion +{ + public string SOI { get; } + public string ROM { get; } + + public SOIROMInclusion(string soi, string rom) + { + SOI = soi; + ROM = rom; + } +} + +public class CaseTypeDRGConfiguration +{ + public int PhysicianMinVolume { get; set; } + public List AgeCohortIDInclusions { get; set; } + public List PhysicianIDExclusions { get; set; } + public int StandardDeviationExcludedTypeEnum { get; set; } + public int LengthOfStayThreshold { get; set; } + public List PatientTypeRollupIDInclusions { get; set; } + public List SOIROMInclusions { get; set; } + public HashSet CCMCCCategories { get; set; } + public HashSet CPTCodes { get; set; } + + public CaseTypeDRGConfiguration() + { + PhysicianMinVolume = 0; + AgeCohortIDInclusions = new List(); + PhysicianIDExclusions = new List(); + PatientTypeRollupIDInclusions = new List(); + StandardDeviationExcludedTypeEnum = 0; + LengthOfStayThreshold = 0; + CCMCCCategories = new HashSet(); + CPTCodes = new HashSet(); + } + +} \ No newline at end of file diff --git a/CaseType Analytics/CaseTypeDestination.linq b/CaseType Analytics/CaseTypeDestination.linq new file mode 100644 index 0000000..de79a47 --- /dev/null +++ b/CaseType Analytics/CaseTypeDestination.linq @@ -0,0 +1,139 @@ + + + 870a756b-af44-4db4-b004-58ff41318b3a + true + P9900-SQL-11.sdt.local + jazz tst GM DSS Share Training Master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private IEnumerable existing_versions; +private IEnumerable existing_migrations; +private IEnumerable existing_families; +private IEnumerable existing_mappings; + +void Main() +{ + Step1(); + + existing_migrations.Dump(); + existing_versions.Dump(); + existing_families.Count().Dump(); + existing_mappings.Count().Dump(); + var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(existing_migrations)}.json"), JsonConvert.SerializeObject(existing_migrations, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(existing_versions)}.json"), JsonConvert.SerializeObject(existing_versions, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(existing_families)}.json"), JsonConvert.SerializeObject(existing_families, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(existing_mappings)}.json"), JsonConvert.SerializeObject(existing_mappings, Newtonsoft.Json.Formatting.Indented)); +} + +// Define other methods and classes here +private void Step1() +{ + existing_migrations = from ml in MigrationLogs where ml.DateTimeStamp > new DateTime(2018, 11, 16) && ml.Name.Replace(" ", "").Contains("CaseType") orderby ml.DateTimeStamp descending select ml.Name; + existing_versions = from ctfv in CaseTypeFamilyVersions select new VersionInfo(ctfv.CaseTypeFamilyVersionID, ctfv.Name, ctfv.StartDate, ctfv.EndDate); + existing_families = from ctf in CaseTypeFamilies select new FamilyInfo(ctf.CaseTypeFamilyGlobalID, ctf.Name, ctf.CaseTypeFamilyID); + existing_mappings = (from ctfm in CaseTypeFamilyMappingICD10s + join family in CaseTypeFamilies on ctfm.CaseTypeFamilyID equals family.CaseTypeFamilyID + where ctfm.CaseTypeFamilyVersionID == 1 + select new MappingInfo(family.CaseTypeFamilyGlobalID, ctfm.SkipICD, ctfm.ICD10Code, ctfm.MSDRGCode)).Distinct(); +} + + +public class VersionInfo +{ + public int CaseTypeFamilyVersionId { get; set; } + public string Name { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + + public VersionInfo(int id, string name, DateTime start, DateTime end) + { + CaseTypeFamilyVersionId = id; + Name = name; + StartDate = start; + EndDate = end; + } +} + +public class FamilyInfo +{ + public int CaseTypeFamilyID { get; set; } + public string CaseTypeFamilyGlobalID { get; set; } + public string Name { get; set; } + + public FamilyInfo(string caseTypeFamilyGlobalID, string name, int caseTypeFamilyID) + { + CaseTypeFamilyID = caseTypeFamilyID; + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + Name = name; + } +} + +public class MappingInfo +{ + public string CaseTypeFamilyGlobalID { get; set; } + public bool SkipICD { get; set; } + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + + public MappingInfo(string caseTypeFamilyGlobalID, bool skipICD, string icd10Code, string msdrgCode) + { + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + SkipICD = skipICD; + ICD10Code = icd10Code; + MSDRGCode = msdrgCode; + } +} diff --git a/CaseType Analytics/CaseTypeFamily Create Corrections.linq b/CaseType Analytics/CaseTypeFamily Create Corrections.linq new file mode 100644 index 0000000..3aa91dd --- /dev/null +++ b/CaseType Analytics/CaseTypeFamily Create Corrections.linq @@ -0,0 +1,286 @@ + + + 870a756b-af44-4db4-b004-58ff41318b3a + true + P9900-SQL-11.sdt.local + jazz tst GM non DSS Share Training Master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private IEnumerable correct_versions; +private IEnumerable correct_migrations; +private IEnumerable correct_families; +private IEnumerable correct_mappings; +private IEnumerable existing_versions; +private IEnumerable existing_migrations; +private IEnumerable existing_families; +private IEnumerable existing_mappings; + +void Main() +{ + //var cts = Util.GetMyQueries().FirstOrDefault(u => u.FilePath.EndsWith("CaseTypeSource.linq")); + //var connStr = cts.GetConnectionInfo().DatabaseInfo.GetCxString(); + Step1(); + Step2(); + + var versions = (from cf in correct_versions + join ef in existing_versions on cf.CaseTypeFamilyVersionId equals ef.CaseTypeFamilyVersionId into cef + from ef in cef.DefaultIfEmpty() + select new { cf, ef }).ToList(); + versions.Dump(nameof(versions)); + var migrations = (from cf in correct_migrations + join ef in existing_migrations on cf equals ef into cef + from ef in cef.DefaultIfEmpty() + select new { cf, ef }).ToList(); + var migrationDeletes = (from cf in existing_migrations + join ef in correct_migrations on cf equals ef into cef + from ef in cef.DefaultIfEmpty() + select new { cf, ef }).ToList(); + var families = (from cf in correct_families + join ef in existing_families on cf.CaseTypeFamilyGlobalID equals ef.CaseTypeFamilyGlobalID into cef + from ef in cef.DefaultIfEmpty() + select new { cf, ef }).ToList(); + var familyDeletes = (from cf in existing_families + join ef in correct_families on cf.CaseTypeFamilyGlobalID equals ef.CaseTypeFamilyGlobalID into cef + from ef in cef.DefaultIfEmpty() + select new { cf, ef }).ToList(); + var mappings = (from cm in correct_mappings + join em in existing_mappings on new { cm.CaseTypeFamilyGlobalID, cm.SkipICD, cm.ICD10Code, cm.MSDRGCode } + equals new { em.CaseTypeFamilyGlobalID, em.SkipICD, em.ICD10Code, em.MSDRGCode } into cem + from em in cem.DefaultIfEmpty() + select new { cm, em }).ToList(); + var mappingDeletes = (from cm in existing_mappings + join em in correct_mappings on new { cm.CaseTypeFamilyGlobalID, cm.SkipICD, cm.ICD10Code, cm.MSDRGCode } + equals new { em.CaseTypeFamilyGlobalID, em.SkipICD, em.ICD10Code, em.MSDRGCode } into cem + from em in cem.DefaultIfEmpty() + select new { cm, em }).ToList(); + + var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + var sql = versions.Where(f => f.ef == null) + .Aggregate(@"", (x, y) => $@"{x} +INSERT INTO [dss].[CaseTypeFamilyVersion] (CaseTypeFamilyVersionId, Name, StartDate, EndDate) +SELECT '{y.cf.CaseTypeFamilyVersionId}', '{y.cf.Name}', '{y.cf.StartDate:G}', '{y.cf.EndDate:G}' +WHERE NOT EXISTS (SELECT 1 FROM [dss].[CaseTypeFamilyVersion] WHERE CaseTypeFamilyVersionId = '{y.cf.CaseTypeFamilyVersionId}'); +"); + if (File.Exists(Path.Combine(documentFolder, $"Case Type Family Corrections 1 ({this.Connection.Database}).sql"))) + File.Delete(Path.Combine(documentFolder, $"Case Type Family Corrections 1 ({this.Connection.Database}).sql")); + if (!string.IsNullOrEmpty(sql.Trim())) + File.WriteAllText(Path.Combine(documentFolder, $"Case Type Family Corrections 1 ({this.Connection.Database}).sql"), sql); + + sql = versions.Where(f => f.ef != null + && ((f.cf.Name != f.ef.Name + && f.cf.Name.Replace("And", "&") != f.ef.Name + && f.cf.Name.Replace(" And ", "&") != f.ef.Name) + || (f.cf.StartDate != f.ef.StartDate) + || (f.cf.EndDate != f.ef.EndDate))) + .Aggregate(@"", (x, y) => $@"{x} +UPDATE [dss].[CaseTypeFamilyVersion] +SET Name = '{y.cf.Name}', StartDate = '{y.cf.StartDate:G}', EndDate = '{y.cf.EndDate:G}' +WHERE CaseTypeFamilyVersionId = '{y.cf.CaseTypeFamilyVersionId}'; -- current name = {y.ef.Name} +"); + if (File.Exists(Path.Combine(documentFolder, $"Case Type Family Corrections 2 ({this.Connection.Database}).sql"))) + File.Delete(Path.Combine(documentFolder, $"Case Type Family Corrections 2 ({this.Connection.Database}).sql")); + if (!string.IsNullOrEmpty(sql.Trim())) + File.WriteAllText(Path.Combine(documentFolder, $"Case Type Family Corrections 2 ({this.Connection.Database}).sql"), sql); + + sql = families.Where(f => f.ef == null) + .Aggregate(@"", (x, y) => $@"{x} +INSERT INTO [dss].[CaseTypeFamily] (CaseTypeFamilyGlobalID, Name) +SELECT '{y.cf.CaseTypeFamilyGlobalID}', '{y.cf.Name}' +WHERE NOT EXISTS (SELECT 1 FROM [dss].[CaseTypeFamily] WHERE CaseTypeFamilyGlobalID = '{y.cf.CaseTypeFamilyGlobalID}'); +"); + if (File.Exists(Path.Combine(documentFolder, $"Case Type Family Corrections 3 ({this.Connection.Database}).sql"))) + File.Delete(Path.Combine(documentFolder, $"Case Type Family Corrections 3 ({this.Connection.Database}).sql")); + if (!string.IsNullOrEmpty(sql.Trim())) + File.WriteAllText(Path.Combine(documentFolder, $"Case Type Family Corrections 3 ({this.Connection.Database}).sql"), sql); + + sql = families.Where(f => f.ef != null + && (f.cf.Name != f.ef.Name + && f.cf.Name.Replace("And", "&") != f.ef.Name + && f.cf.Name.Replace(" And ", "&") != f.ef.Name)) + .Aggregate(@"", (x, y) => $@"{x} +UPDATE [dss].[CaseTypeFamily] +SET Name = '{y.cf.Name}' +WHERE CaseTypeFamilyGlobalID = '{y.cf.CaseTypeFamilyGlobalID}'; -- current name = {y.ef.Name} +"); + if (File.Exists(Path.Combine(documentFolder, $"Case Type Family Corrections 4 ({this.Connection.Database}).sql"))) + File.Delete(Path.Combine(documentFolder, $"Case Type Family Corrections 4 ({this.Connection.Database}).sql")); + if (!string.IsNullOrEmpty(sql.Trim())) + File.WriteAllText(Path.Combine(documentFolder, $"Case Type Family Corrections 4 ({this.Connection.Database}).sql"), sql); + + var insert = sql = mappings.Where(f => f.em == null).Any() + ? @"INSERT INTO [dss].[CaseTypeFamilyMappingICD10] ([CaseTypeFamilyID], [SkipICD], [ICD10Code], [MSDRGCode], [CaseTypeFamilyVersionID]) +" : ""; + var selects = mappings.Where(f => f.em == null) + .Select((y, idx) => new { query = $@"SELECT [CaseTypeFamilyID], {(y.cm.SkipICD ? 1 : 0)}, '{y.cm.ICD10Code}', '{y.cm.MSDRGCode}', 1 FROM [dss].[CaseTypeFamily] WHERE [CaseTypeFamilyGlobalID] = '{y.cm.CaseTypeFamilyGlobalID}'", idx }) + .GroupBy(g => g.idx / 1000, (g, d) => d) + .Select(z => insert + string.Join("\r\nUNION ALL\r\n", z.Select(y => y.query))); + Enumerable.Range(0, 999).ToList() + .ForEach(y => + { + if (File.Exists(Path.Combine(documentFolder, $"Case Type Family Corrections 3{y:000} ({this.Connection.Database}).sql"))) + File.Delete(Path.Combine(documentFolder, $"Case Type Family Corrections 3{y:000} ({this.Connection.Database}).sql")); + }); + selects.ForEach((x, y) => File.WriteAllText(Path.Combine(documentFolder, $"Case Type Family Corrections 3{y:000} ({this.Connection.Database}).sql"), x)); + + versions.Where(f => f.ef == null).Dump("missing versions"); + migrations.Where(f => f.ef == null).Dump("missing migrations"); + migrationDeletes.Where(f => f.ef == null).Dump("migrations to delete"); + families.Where(f => f.ef == null).Dump("missing families"); + families.Where(f => f.ef != null + && (f.cf.Name != f.ef.Name + && f.cf.Name.Replace("And", "&") != f.ef.Name + && f.cf.Name.Replace(" And ", "&") != f.ef.Name)).Dump("families to update"); + familyDeletes.Where(f => f.ef == null).Dump("families to detele"); + mappings.Where(f => f.em == null).Dump("missing mappings"); + mappings.Where(f => f.em != null && (f.cm.SkipICD != f.em.SkipICD || f.cm.ICD10Code != f.em.ICD10Code || f.cm.MSDRGCode != f.em.MSDRGCode)).Dump("mappings to update"); + mappingDeletes.Where(f => f.em == null).Dump("mappings to delete"); + +} + + +// Define other methods and classes here + +/// +/// Connect to P2680-SQL-03 - jazz prd Mercy Health 20160308.1 +/// +private void Step1(string connectionString) +{ + var currentConnection = this.Connection.ConnectionString; + this.Connection.ConnectionString = connectionString; + this.Connection.Dump(); + + correct_migrations = from ml in MigrationLogs + where ml.Name.Replace(" ", "").Contains("CaseType") //&& ml.DateTimeStamp > new DateTime(2018, 11, 16) + orderby ml.DateTimeStamp descending + select ml.Name; + correct_versions = from ctfv in CaseTypeFamilyVersions select new VersionInfo(ctfv.CaseTypeFamilyVersionID, ctfv.Name, ctfv.StartDate, ctfv.EndDate); + correct_families = from ctf in CaseTypeFamilies select new FamilyInfo(ctf.CaseTypeFamilyGlobalID, ctf.Name, ctf.CaseTypeFamilyID); + correct_mappings = (from ctfm in CaseTypeFamilyMappingICD10s + join family in CaseTypeFamilies on ctfm.CaseTypeFamilyID equals family.CaseTypeFamilyID + where ctfm.CaseTypeFamilyVersionID == 1 + select new MappingInfo(family.CaseTypeFamilyGlobalID, ctfm.SkipICD, ctfm.ICD10Code, ctfm.MSDRGCode)).Distinct(); + + this.Connection.ConnectionString = currentConnection; +} + +private void Step1() +{ + var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + correct_migrations = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(documentFolder, $"{nameof(correct_migrations)}.json"))); + correct_versions = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(documentFolder, $"{nameof(correct_versions)}.json"))); + correct_families = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(documentFolder, $"{nameof(correct_families)}.json"))); + correct_mappings = JsonConvert.DeserializeObject>(File.ReadAllText(Path.Combine(documentFolder, $"{nameof(correct_mappings)}.json"))); +} + +private void Step2() +{ + existing_migrations = from ml in MigrationLogs + where ml.Name.Replace(" ", "").Contains("CaseType") //&& ml.DateTimeStamp > new DateTime(2018, 11, 16) + orderby ml.DateTimeStamp + select ml.Name; + existing_versions = from ctfv in CaseTypeFamilyVersions select new VersionInfo(ctfv.CaseTypeFamilyVersionID, ctfv.Name, ctfv.StartDate, ctfv.EndDate); + existing_families = from ctf in CaseTypeFamilies select new FamilyInfo(ctf.CaseTypeFamilyGlobalID, ctf.Name, ctf.CaseTypeFamilyID); + existing_mappings = (from ctfm in CaseTypeFamilyMappingICD10s + join family in CaseTypeFamilies on ctfm.CaseTypeFamilyID equals family.CaseTypeFamilyID + where ctfm.CaseTypeFamilyVersionID == 1 + select new MappingInfo(family.CaseTypeFamilyGlobalID, ctfm.SkipICD, ctfm.ICD10Code, ctfm.MSDRGCode)).Distinct(); +} + +public class VersionInfo +{ + public int CaseTypeFamilyVersionId { get; set; } + public string Name { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + + public VersionInfo(int id, string name, DateTime start, DateTime end) + { + CaseTypeFamilyVersionId = id; + Name = name; + StartDate = start; + EndDate = end; + } +} + +public class FamilyInfo +{ + public int CaseTypeFamilyID { get; set; } + public string CaseTypeFamilyGlobalID { get; set; } + public string Name { get; set; } + + public FamilyInfo(string caseTypeFamilyGlobalID, string name, int caseTypeFamilyID) + { + CaseTypeFamilyID = caseTypeFamilyID; + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + Name = name; + } +} + +public class MappingInfo +{ + public string CaseTypeFamilyGlobalID { get; set; } + public bool SkipICD { get; set; } + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + + public MappingInfo(string caseTypeFamilyGlobalID, bool skipICD, string icd10Code, string msdrgCode) + { + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + SkipICD = skipICD; + ICD10Code = icd10Code; + MSDRGCode = msdrgCode; + } +} \ No newline at end of file diff --git a/CaseType Analytics/CaseTypeFamily Run Corrections.linq b/CaseType Analytics/CaseTypeFamily Run Corrections.linq new file mode 100644 index 0000000..42bf361 --- /dev/null +++ b/CaseType Analytics/CaseTypeFamily Run Corrections.linq @@ -0,0 +1,79 @@ + + + 870a756b-af44-4db4-b004-58ff41318b3a + true + P9900-SQL-11.sdt.local + jazz tst GM non DSS Share Training Master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + var files = Directory.GetFiles(documentFolder, "Case Type Family Corrections*.sql") + .Select(d => Path.GetFileName(d)) + .OrderBy(d => d) + .ToList(); + files.ForEach(f => + { + "".Dump(f); + var query = File.ReadAllText(Path.Combine(documentFolder, f)); + this.ExecuteCommand(query); + }); + + +} + +// Define other methods and classes here diff --git a/CaseType Analytics/CaseTypeSource.linq b/CaseType Analytics/CaseTypeSource.linq new file mode 100644 index 0000000..6439e51 --- /dev/null +++ b/CaseType Analytics/CaseTypeSource.linq @@ -0,0 +1,142 @@ + + + 94a82e0d-b8c1-4789-96cc-f34a75ba3c45 + true + P2980-SQL-03.sdt.local + jazz prd Mercy Health 20160308.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private IEnumerable correct_versions; +private IEnumerable correct_migrations; +private IEnumerable correct_families; +private IEnumerable correct_mappings; + +void Main() +{ + Step1(); + + correct_migrations.Dump(); + correct_versions.Dump(); + correct_families.Count().Dump(); + correct_mappings.Count().Dump(); + var documentFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(correct_migrations)}.json"), JsonConvert.SerializeObject(correct_migrations, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(correct_versions)}.json"), JsonConvert.SerializeObject(correct_versions, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(correct_families)}.json"), JsonConvert.SerializeObject(correct_families, Newtonsoft.Json.Formatting.Indented)); + File.WriteAllText(Path.Combine(documentFolder, $"{nameof(correct_mappings)}.json"), JsonConvert.SerializeObject(correct_mappings, Newtonsoft.Json.Formatting.Indented)); +} + +// Define other methods and classes here +private void Step1() +{ + correct_migrations = from ml in MigrationLogs + where ml.Name.Replace(" ", "").Contains("CaseType") //&& ml.DateTimeStamp > new DateTime(2018, 11, 16) + orderby ml.DateTimeStamp descending + select ml.Name; + correct_versions = from ctfv in CaseTypeFamilyVersions select new VersionInfo(ctfv.CaseTypeFamilyVersionID, ctfv.Name, ctfv.StartDate, ctfv.EndDate); + correct_families = from ctf in CaseTypeFamilies select new FamilyInfo(ctf.CaseTypeFamilyGlobalID, ctf.Name, ctf.CaseTypeFamilyID); + correct_mappings = (from ctfm in CaseTypeFamilyMappingICD10s + join family in CaseTypeFamilies on ctfm.CaseTypeFamilyID equals family.CaseTypeFamilyID + where ctfm.CaseTypeFamilyVersionID == 1 + select new MappingInfo(family.CaseTypeFamilyGlobalID, ctfm.SkipICD, ctfm.ICD10Code, ctfm.MSDRGCode)).Distinct(); +} + + +public class VersionInfo +{ + public int CaseTypeFamilyVersionId { get; set; } + public string Name { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + + public VersionInfo(int id, string name, DateTime start, DateTime end) + { + CaseTypeFamilyVersionId = id; + Name = name; + StartDate = start; + EndDate = end; + } +} + +public class FamilyInfo +{ + public int CaseTypeFamilyID { get; set; } + public string CaseTypeFamilyGlobalID { get; set; } + public string Name { get; set; } + + public FamilyInfo(string caseTypeFamilyGlobalID, string name, int caseTypeFamilyID) + { + CaseTypeFamilyID = caseTypeFamilyID; + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + Name = name; + } +} + +public class MappingInfo +{ + public string CaseTypeFamilyGlobalID { get; set; } + public bool SkipICD { get; set; } + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + + public MappingInfo(string caseTypeFamilyGlobalID, bool skipICD, string icd10Code, string msdrgCode) + { + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + SkipICD = skipICD; + ICD10Code = icd10Code; + MSDRGCode = msdrgCode; + } +} diff --git a/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 SkipICD.linq b/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 SkipICD.linq new file mode 100644 index 0000000..2e8a5c6 --- /dev/null +++ b/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 SkipICD.linq @@ -0,0 +1,788 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private string text = @"1 558 M-296 +1 987 M-345 +1 895 M-16 +1 670 M-304 +1 445 M-98 +1 599 A-19 +1 505 M-125 +1 033 M-322 +1 247 M-229 +1 881 M-90 +1 294 M-100 +1 605 M-305 +1 208 M-367 +1 163 M-177 +1 248 M-230 +1 182 M-262 +1 637 A-6 +1 287 M-337 +1 815 M-264 +1 344 M-194 +1 387 A-13 +1 281 M-5 +1 985 M-249 +1 923 M-354 +1 896 M-17 +1 920 M-338 +1 230 A-21 +1 975 M-142 +1 504 M-125 +1 754 M-187 +1 950 M-13 +1 263 M-321 +1 579 M-362 +1 034 M-231 +1 595 A-18 +1 574 M-277 +1 472 M-61 +1 258 M-56 +1 776 M-245 +1 200 M-241 +1 336 A-24 +1 603 M-58 +1 334 M-253 +1 729 M-217 +1 816 M-264 +1 158 M-89 +1 485 M-163 +1 310 M-328 +1 555 M-274 +1 600 M-204 +1 661 M-162 +1 849 A-26 +1 939 M-346 +1 389 M-131 +1 187 M-239 +1 410 M-283 +1 712 M-297 +1 333 M-253 +1 186 M-239 +1 510 M-222 +1 343 M-29 +1 865 A-32 +1 790 M-116 +1 183 M-178 +1 501 M-280 +1 578 M-276 +1 809 M-182 +1 781 M-25 +1 750 M-214 +1 150 M-108 +1 350 M-152 +1 770 M-281 +1 335 A-24 +1 453 M-27 +1 053 M-288 +1 474 M-21 +1 424 M-353 +1 709 M-228 +1 178 M-261 +1 561 M-72 +1 100 M-270 +1 710 M-228 +1 556 M-274 +1 416 M-65 +1 123 M-201 +1 935 M-203 +1 516 M-357 +1 355 M-140 +1 215 M-137 +1 189 M-251 +1 094 M-34 +1 064 M-59 +1 685 M-8 +1 617 M-22 +1 759 A-9 +1 464 M-323 +1 725 M-36 +1 664 M-193 +1 789 M-344 +1 167 M-361 +1 292 A-12 +1 800 A-29 +1 509 M-30 +1 668 M-304 +1 069 A-31 +1 594 A-27 +1 882 M-202 +1 663 M-193 +1 314 A-22 +1 767 M-318 +1 489 M-164 +1 871 M-273 +1 688 M-161 +1 959 M-359 +1 667 M-248 +1 455 M-27 +1 675 M-355 +1 006 M-169 +1 155 M-213 +1 228 A-21 +1 059 M-88 +1 760 M-118 +1 843 M-220 +1 903 M-111 +1 070 M-60 +1 031 M-322 +1 495 M-109 +1 779 M-1 +1 928 M-129 +1 179 M-261 +1 222 M-55 +1 371 M-180 +1 381 M-70 +1 949 M-13 +1 298 M-52 +1 792 M-247 +1 285 M-6 +1 308 M-328 +1 221 M-285 +1 657 M-159 +1 264 M-349 +1 028 A-28 +1 639 A-6 +1 511 M-222 +1 500 M-280 +1 695 M-158 +1 180 M-262 +1 176 A-25 +1 674 M-355 +1 037 M-115 +1 945 M-105 +1 597 A-19 +1 478 M-41 +1 841 M-172 +1 869 M-150 +1 306 M-75 +1 948 M-368 +1 570 M-329 +1 654 A-15 +1 138 M-196 +1 908 M-358 +1 434 M-66 +1 538 M-291 +1 559 M-72 +1 965 M-356 +1 202 M-48 +1 557 M-296 +1 689 M-160 +1 244 M-234 +1 446 M-98 +1 101 M-270 +1 723 M-189 +1 225 M-54 +1 835 M-4 +1 549 M-272 +1 262 M-57 +1 964 M-356 +1 956 M-167 +1 376 A-7 +1 437 M-188 +1 135 M-275 +1 352 M-152 +1 984 M-249 +1 226 M-53 +1 283 M-6 +1 218 M-284 +1 370 A-16 +1 540 M-209 +1 191 M-77 +1 534 M-120 +1 602 M-58 +1 982 M-114 +1 148 M-102 +1 838 M-62 +1 007 M-171 +1 293 A-12 +1 097 M-287 +1 280 M-5 +1 498 M-110 +1 746 M-317 +1 830 M-199 +1 272 M-334 +1 067 M-205 +1 458 M-290 +1 078 M-146 +1 147 M-102 +1 345 M-194 +1 071 M-60 +1 295 M-100 +1 096 M-34 +1 235 M-49 +1 385 A-13 +1 624 M-279 +1 499 M-110 +1 922 M-354 +1 234 M-50 +1 423 M-353 +1 989 M-345 +1 715 M-186 +1 765 M-84 +1 934 M-128 +1 550 M-272 +1 137 M-196 +1 918 M-242 +1 056 M-86 +1 958 M-359 +1 868 M-150 +1 207 M-366 +1 250 M-232 +1 442 M-99 +1 826 M-342 +1 671 M-311 +1 062 M-293 +1 201 M-241 +1 165 M-177 +1 257 M-371 +1 441 M-99 +1 565 M-198 +1 421 M-139 +1 886 M-35 +1 625 M-298 +1 085 M-306 +1 354 M-140 +1 074 M-80 +1 038 M-115 +1 113 A-20 +1 791 M-246 +1 393 M-210 +1 660 M-162 +1 857 M-244 +1 904 M-278 +1 630 M-351 +1 940 M-346 +1 197 M-153 +1 241 M-282 +1 273 M-333 +1 330 M-175 +1 390 M-131 +1 195 M-240 +1 456 M-290 +1 814 M-264 +1 713 M-308 +1 866 A-32 +1 553 M-43 +1 010 A-23 +1 747 M-317 +1 804 M-360 +1 125 M-211 +1 473 M-61 +1 700 M-216 +1 755 M-187 +1 341 M-29 +1 933 M-113 +1 340 M-28 +1 496 M-109 +1 023 M-339 +1 289 M-7 +1 239 M-282 +1 963 M-356 +1 149 M-101 +1 159 M-89 +1 618 M-22 +1 515 M-357 +1 309 M-328 +1 193 M-240 +1 444 M-98 +1 242 M-234 +1 076 A-33 +1 577 M-276 +1 432 M-66 +1 029 A-28 +1 032 M-322 +1 691 M-313 +1 300 M-233 +1 016 M-32 +1 408 M-283 +1 435 M-188 +1 622 M-279 +1 870 M-271 +1 249 M-230 +1 502 M-280 +1 388 M-131 +1 662 M-193 +1 757 A-9 +1 828 M-342 +1 282 M-5 +1 604 M-305 +1 854 M-341 +1 573 M-277 +1 793 M-127 +1 554 M-43 +1 699 M-216 +1 058 M-88 +1 008 M-225 +1 339 M-28 +1 902 M-111 +1 223 M-55 +1 542 M-227 +1 115 M-286 +1 592 A-27 +1 269 M-332 +1 316 A-22 +1 846 M-63 +1 231 M-51 +1 768 M-319 +1 707 A-17 +1 665 M-248 +1 268 M-332 +1 883 M-235 +1 483 M-183 +1 856 M-244 +1 497 M-109 +1 134 M-350 +1 955 A-5 +1 642 M-76 +1 332 M-253 +1 181 M-262 +1 129 M-181 +1 976 M-142 +1 947 M-368 +1 139 M-269 +1 151 M-108 +1 718 M-218 +1 842 M-172 +1 440 M-97 +1 052 M-288 +1 040 M-363 +1 156 M-213 +1 229 A-21 +1 544 M-227 +1 847 M-63 +1 844 M-220 +1 382 M-70 +1 862 M-243 +1 077 M-146 +1 641 M-207 +1 572 M-329 +1 780 A-8 +1 744 M-85 +1 658 M-159 +1 927 M-112 +1 820 M-173 +1 216 M-284 +1 643 M-106 +1 166 M-361 +1 290 M-7 +1 233 M-50 +1 855 M-341 +1 083 M-307 +1 824 M-174 +1 411 M-64 +1 696 M-158 +1 304 A-128 +1 409 M-283 +1 055 M-200 +1 102 M-136 +1 655 A-15 +1 378 M-130 +1 520 M-335 +1 666 M-248 +1 687 M-161 +1 693 M-312 +1 079 M-146 +1 099 M-287 +1 307 M-75 +1 914 M-370 +1 327 M-369 +1 539 M-209 +1 722 M-189 +1 546 A-4 +1 133 M-350 +1 834 M-4 +1 969 M-340 +1 368 A-16 +1 375 A-7 +1 894 M-18 +1 297 M-52 +1 457 M-290 +1 717 M-218 +1 004 M-301 +1 383 M-309 +1 303 M-31 +1 065 M-59 +1 724 M-189 +1 728 M-151 +1 801 A-29 +1 255 M-371 +1 014 M-19 +1 672 M-311 +1 880 M-2 +1 291 A-12 +1 863 M-243 +1 232 M-51 +1 017 M-32 +1 256 M-371 +1 130 M-181 +1 063 M-293 +1 417 M-166 +1 296 M-52 +1 748 M-119 +1 475 M-21 +1 438 M-97 +1 734 M-252 +1 745 M-85 +1 970 M-340 +1 545 A-4 +1 593 A-27 +1 566 M-198 +1 425 M-353 +1 897 M-17 +1 487 M-163 +1 974 M-142 +1 627 M-298 +1 560 M-72 +1 562 M-197 +1 575 M-277 +1 177 M-261 +1 068 M-205 +1 271 M-334 +1 337 A-24 +1 782 M-26 +1 198 M-153 +1 203 M-48 +1 629 M-351 +1 199 M-241 +1 486 M-163 +1 714 M-308 +1 095 M-34 +1 623 M-279 +1 087 M-306 +1 917 M-242 +1 876 M-347 +1 716 M-186 +1 227 M-53 +1 380 M-70 +1 988 M-345 +1 517 M-357 +1 188 M-239 +1 152 M-223 +1 374 A-7 +1 284 M-6 +1 506 M-185 +1 711 M-297 +1 082 M-307 +1 802 M-360 +1 116 M-157 +1 795 M-206 +1 184 M-178 +1 395 M-210 +1 420 M-139 +1 073 M-80 +1 628 M-351 +1 921 M-338 +1 794 M-343 +1 114 A-20 +1 606 M-195 +1 286 M-337 +1 596 A-18 +1 035 M-231 +1 260 M-57 +1 415 M-65 +1 887 M-219 +1 471 M-61 +1 829 M-199 +1 645 M-106 +1 217 M-284 +1 146 M-102 +1 346 M-194 +1 758 A-9 +1 708 A-17 +1 827 M-342 +1 192 M-77 +1 351 M-152 +1 329 M-175 +1 205 M-221 +1 338 M-28 +1 541 M-209 +1 245 M-14 +1 749 M-214 +1 463 M-323 +1 086 M-306 +1 164 M-177 +1 769 M-364 +1 342 M-29 +1 601 M-204 +1 808 M-182 +1 386 A-13 +1 204 M-263 +1 810 M-182 +1 243 M-234 +1 454 M-27 +1 259 M-56 +1 837 M-62 +1 117 M-157 +1 433 M-66 +1 288 M-7 +1 813 M-68 +1 075 A-33 +1 576 M-276 +1 885 M-250 +1 692 M-313 +1 981 M-114 +1 224 M-54 +1 652 A-14 +1 261 M-57 +1 512 M-222 +1 372 M-180 +1 799 A-29 +1 686 M-161 +1 190 M-77 +1 638 A-6 +1 042 M-363 +1 465 M-323 +1 313 A-3 +1 414 M-65 +1 024 M-339 +1 598 A-19 +1 246 M-229 +1 519 M-335 +1 236 M-49 +1 547 A-4 +1 543 M-227 +1 946 M-105 +1 777 M-104 +1 419 M-166 +1 477 M-41 +1 840 M-172 +1 533 M-120 +1 659 M-162 +1 270 M-334 +1 872 M-273 +1 864 A-10 +1 154 M-213 +1 479 M-41 +1 909 M-358 +1 823 M-174 +1 503 M-125 +1 194 M-240 +1 735 M-252 +1 951 M-352 +1 030 A-28 +1 583 M-190 +1 656 M-159 +1 418 M-166 +1 690 M-160 +1 379 M-130 +1 326 M-369 +1 929 M-129 +1 518 M-335 +1 311 M-24 +1 157 M-89 +1 436 M-188 +1 041 M-363 +1 673 M-355 +1 582 M-190 +1 413 M-64 +1 853 M-341 +1 756 M-187 +1 124 M-211 +1 168 M-361 +1 901 M-111 +1 089 M-74 +1 581 M-362 +1 036 M-231 +1 775 M-327 +1 373 M-180 +1 913 M-370 +1 669 M-304 +1 301 M-233 +1 122 A-1 +1 312 M-294 +1 653 A-15 +1 315 A-22 +1 571 M-329 +1 039 M-115 +1 697 M-310 +1 369 A-16 +1 858 M-244 +1 551 M-192 +1 412 M-64 +1 265 M-15 +1 061 M-293 +1 084 M-307 +1 825 M-174 +1 088 M-74 +1 727 M-151 +1 240 M-282 +1 443 M-99 +1 054 M-200 +1 778 A-30 +1 730 M-217 +1 836 M-4 +1 185 M-178 +1 072 M-60 +1 220 M-285 +1 377 M-130 +1 175 A-25 +1 121 A-1 +1 353 M-140 +1 057 M-86 +1 867 M-150 +1 919 M-338 +1 274 M-333 +1 726 M-36 +1 644 M-106 +1 537 M-291 +1 552 M-192 +1 983 M-114 +1 328 M-369 +1 821 M-173 +1 564 M-198 +1 626 M-298 +1 098 M-287 +1 219 M-285 +1 060 M-88 +1 394 M-210 +1 384 M-309 +1 822 M-173 +1 136 M-275 +1 607 M-195 +1 153 M-223 +1 905 M-278 +1 616 M-22 +1 331 M-175 +1 066 M-59 +1 580 M-362 +1 907 M-358 +1 196 M-153 +1 476 M-21 +1 941 M-346 +1 548 M-272 +1 698 M-216 +1 439 M-97 +1 206 M-221 +1 916 A-2 +1 305 A-128 +1 803 M-360 +1 103 M-136 +1 251 M-232 +1 766 M-84 +1 915 A-2 +1 299 M-233 +1 563 M-197 +1 848 M-63 +1 986 M-249 +1 694 M-312 +1 957 M-359 +1 977 M-143 +1 845 M-220 +1 090 M-74 +1 488 M-164 +1 302 M-31 +1 839 M-62 +1 422 M-139 +1 761 M-118 +1 640 M-207 +1 774 M-330 +1 0 783 M-412 +1 0 784 M-412 +1 0 785 M-412 +1 0 786 M-413 +1 0 787 M-413 +1 0 788 M-413 +1 0 805 M-414 +1 0 806 M-414 +1 0 807 M-414 +1 0 817 M-415 +1 0 818 M-415 +1 0 819 M-415 +1 0 831 M-416 +1 0 832 M-416 +1 0 833 M-416 +1 0 796 M-318 +1 0 797 M-318 +1 0 798 M-318"; + +void Main() +{ + var mappings = text.Replace("\r\n", "\r").Split('\r') + .Where(r => !string.IsNullOrEmpty(r) && r.Split('\t').Length == 4) // There must be exactly 4 columns in each row of data + .Select(x => + { + var column = x.Split('\t'); + return new CaseTypeFamilyMapping(column[0], column[1], column[2], column[3], 0); + }); + mappings.Where(m => m != null).OrderBy(m => m.SkipICD).ThenBy(m => m.ICD10Code).ThenBy(m => m.MSDRGCode).ThenBy(m => m.GlobalID).Dump(); +} + +public class CaseTypeFamilyMapping +{ + public bool SkipICD { get; set; } + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + public string GlobalID { get; set; } + public int CaseTypeFamilyId { get; set; } + + public CaseTypeFamilyMapping(string skipICD, string icd10Code, string msdrgCode, string globalID, int caseTypeFamilyId) + { + if (!bool.TryParse(skipICD, out bool skipped)) skipped = false; + SkipICD = (skipICD == "1"); + ICD10Code = icd10Code; + MSDRGCode = msdrgCode; + GlobalID = globalID; + //CaseTypeFamilyId = caseTypeFamilyId; + } + +} diff --git a/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 table.linq b/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 table.linq new file mode 100644 index 0000000..6b64b51 --- /dev/null +++ b/CaseType Analytics/Cleanup CaseTypeFamilyMappingICD10 table.linq @@ -0,0 +1,134 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var grps = CaseTypeFamilyMappingICD10s +.Where(ctf => ctf.CaseTypeFamilyVersionID == 2) +.GroupBy(ctf => new { ctf.CaseTypeFamilyID, ctf.ICD10Code }) +.OrderBy(grp => grp.Key.CaseTypeFamilyID) +.ThenBy(grp => grp.Key.ICD10Code) +.Select(grp => new { grp.Key.CaseTypeFamilyID, grp.Key.ICD10Code, count = grp.Count() }); + +var grpBreak = 100000; +var pageSize = 10000; +foreach (var grp in grps) +{ + grp.Dump(); + if (grp.count > grpBreak) + { + var subgrps = CaseTypeFamilyMappingICD10s + .Where(ctf => ctf.CaseTypeFamilyVersionID == 2) + .GroupBy(ctf => new { ctf.CaseTypeFamilyID, ctf.ICD10Code, ctf.MSDRGCode }) + .OrderBy(subgrp => subgrp.Key.CaseTypeFamilyID) + .ThenBy(subgrp => subgrp.Key.ICD10Code) + .ThenBy(subgrp => subgrp.Key.MSDRGCode) + .Select(subgrp => new { subgrp.Key.CaseTypeFamilyID, subgrp.Key.ICD10Code, subgrp.Key.MSDRGCode, count = subgrp.Count() }); + + foreach (var subgrp in subgrps) + { + subgrp.Dump(); + var subgrpremove = from mapping in CaseTypeFamilyMappingICD10s + where mapping.CaseTypeFamilyID == subgrp.CaseTypeFamilyID + && mapping.ICD10Code == subgrp.ICD10Code + && mapping.MSDRGCode == subgrp.MSDRGCode + && mapping.CaseTypeFamilyVersionID == 2 + select mapping; + + if (subgrpremove.Any()) + { + var pages = ((subgrp.count + (pageSize - 1)) / pageSize); + Enumerable.Range(0, pages).ToList() + .ForEach(page => + { + $"{(page + 1)} of {pages}".Dump(); + var workSet = subgrpremove.Skip(page * pageSize).Take(pageSize).ToList(); + CaseTypeFamilyMappingICD10s.DeleteAllOnSubmit(workSet); + SubmitChanges(); + }); + } + } + continue; + } + var remove = from mapping in CaseTypeFamilyMappingICD10s + where mapping.CaseTypeFamilyID == grp.CaseTypeFamilyID + && mapping.ICD10Code == grp.ICD10Code + && mapping.CaseTypeFamilyVersionID == 2 + select mapping; + + if (remove.Any()) + { + var pages = ((grp.count + (pageSize - 1)) / pageSize); + Enumerable.Range(0, pages).ToList() + .ForEach(page => + { + $"{(page + 1)} of {pages}".Dump(); + var workSet = remove.Skip(page * pageSize).Take(pageSize).ToList(); + CaseTypeFamilyMappingICD10s.DeleteAllOnSubmit(workSet); + SubmitChanges(); + }); + } +} \ No newline at end of file diff --git a/Create CCI StoreProc Unit Tests.linq b/Create CCI StoreProc Unit Tests.linq new file mode 100644 index 0000000..d752e28 --- /dev/null +++ b/Create CCI StoreProc Unit Tests.linq @@ -0,0 +1,107 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var routines = @"procCleanupOpportunities +procDeleteAllData +procDeleteDimensionData +procEpicADTInitializeDepartmentPatientCensus +procInsertDimensionDefaults +procOptimizationRebuildIndexesDimensions +procPatientCensusDiscardIncorrectEntries +procPatientEncounterSummaryUpdateCaseTypeId +procPopulateCustomOpportunitySavings +procPopulateDepartmentPatientCensus +procPopulateDepartmentPatientCensusFromCerner +procPopulateDepartmentPatientCensusFromMeditech +procPopulateDepartmentPatientCensusFromStarADT +procPopulateDepartmentPatientDailyCensus +procPopulatePhysicianQualityMetrics +procSampleCaseTypeFamilyMetricsAll +procSampleChargeCodeConfigs +procSampleMSDRGCaseTypeFamilyMetrics +procSampleNursingDepartments +procSampleNursingMonthlyVolume +procSampleUNSPSCRollup +procUpdateDimInitiative +procUpdateDimOpportunity +procUpdateFactOpportunityMetric +procUpdateFactOpportunitySavings".Replace("\r\n", "\r").Split('\r'); +var bools = new[] { true }; //, false }; +var groups = new[] { 2, 3 }; +var variations = (from b in bools + from g in groups + from r in routines + select new { b = b && g != 1, g, r, q = g == 1 ? "NoQuery" : g == 2 ? "DataSet" : g == 3 ? "Datatable" : "Scalar" }) + .Distinct() + .Where(v => v.r != "procPopulateCustomOpportunitySavings") + .OrderBy(o => o.q) + .ThenBy(o => o.r) + .ThenByDescending(o => o.b).ToList(); + +//variations.Dump(); + +variations.ForEach(v => $@" [Test] + public void TestxCci{v.r}{v.g}_{v.q}() + {{ + var contextMock = new Mock().As(); + + using (contextMock.InScope()) + {{ + {(v.b ? "var ts = (int)TimeSpan.FromMinutes(5).TotalSeconds;\r\n " : "")}Action act = () => {v.r}.Execute{v.q}({(v.b ? "Guid.NewGuid()" : "")}); + act.Should().NotThrow(); + }} + + contextMock.VerifyStoredProc<{v.r}>({(v.b ? "TimeSpan.FromMinutes(5), " : "")}Times.Never()); + }} +".Dump()); \ No newline at end of file diff --git a/Create CPT CaseTypeFamily entries.linq b/Create CPT CaseTypeFamily entries.linq new file mode 100644 index 0000000..d69d265 --- /dev/null +++ b/Create CPT CaseTypeFamily entries.linq @@ -0,0 +1,171 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var opcptcodefile = @"D:\Users\tlamb\Downloads\OP CTF_03232020.txt"; +var opcptcodelist = File.ReadAllLines(opcptcodefile); +var opcptcodes = opcptcodelist.Skip(1).Select(o => new { CaseTypeFamily = o.Split('\t')[0], CPTCode = o.Split('\t')[1].Trim() }); + +var newCaseTypeFamily = from op in opcptcodes + join ctf in CaseTypeFamilies on op.CaseTypeFamily equals ctf.Name into joined + from j in joined.DefaultIfEmpty() + where j == null + select op.CaseTypeFamily; + +var newCaseTypeFamilies = +@"--Author: tlamb +--Version: 2020.21 +--Forward +update pes set pes.MSDRGCaseTypeFamilyID = 0, pes.APRDRGCaseTypeFamilyID = 0 +from [clientdss].[FactPatientEncounterSummary] pes +INNER JOIN fw.DimPatientType pt on pt.PatientTypeID = pes.PatientTypeID +INNER JOIN fw.DimPatientTypeRollup ptr on pt.PatientTypeRollupID = ptr.PatientTypeRollupID +where ptr.Type <> 'Inpatient'; +GO +DELETE FROM dss.CaseTypeFamily WHERE CaseTypeFamilyGlobalID LIKE 'O-%'; +GO +DELETE FROM dss.CaseTypeFamilyMappingCPT; +GO +" + +string.Join("\r\n", opcptcodes +.Select(o => o.CaseTypeFamily) +.Distinct().OrderBy(ctf => ctf) +.Select((ctf, i) => new {i, value = $"\t( NEWID(), N'{ctf}', N'O-{(i + 1):0000}' )"}) +.GroupBy(ctf => (int)ctf.i / 100, (g, d) => string.Join(",\r\n", d.Select(v => v.value))) +.Select(ctf => $"INSERT INTO dss.CaseTypeFamily ( CaseTypeFamilyGUID, Name, CaseTypeFamilyGlobalID )\r\nVALUES\r\n{ctf};\r\nGO")) + +@" +DECLARE @CaseTypeFamilyVersionID INT; +SELECT @CaseTypeFamilyVersionID = CaseTypeFamilyVersionID FROM dss.CaseTypeFamilyVersion AS ctfv WHERE GETDATE() BETWEEN ctfv.StartDate AND ctfv.EndDate; +" + +string.Join("\r\n", opcptcodes +.Select(o => $@"INSERT INTO dss.CaseTypeFamilyMappingCPT ( CaseTypeFamilyID, CPTCode, CaseTypeFamilyVersionID ) +SELECT CaseTypeFamilyID, '{o.CPTCode}', @CaseTypeFamilyVersionID +FROM dss.CaseTypeFamily AS ctf WHERE ctf.Name = '{o.CaseTypeFamily}'")) + @" +GO +--Rollback +update pes set pes.MSDRGCaseTypeFamilyID = 0, pes.APRDRGCaseTypeFamilyID = 0 +from [clientdss].[FactPatientEncounterSummary] pes +INNER JOIN fw.DimPatientType pt on pt.PatientTypeID = pes.PatientTypeID +INNER JOIN fw.DimPatientTypeRollup ptr on pt.PatientTypeRollupID = ptr.PatientTypeRollupID +where ptr.Type <> 'Inpatient'; +GO +DELETE FROM dss.CaseTypeFamily WHERE CaseTypeFamilyGlobalID LIKE 'O-%'; +GO +DELETE FROM dss.CaseTypeFamilyMappingCPT; +GO +"; +File.WriteAllText(@"D:\Git\jazz\Migrations\CCI\2020-03-25-15-34 D-09502 OP CaseTypeFamily Definitions 2.sql", newCaseTypeFamilies); +newCaseTypeFamilies.Dump(nameof(newCaseTypeFamilies)); + +/* +var dbResults = from ctfmc in CaseTypeFamilyMappingCPTs + join ctf in CaseTypeFamilies on ctfmc.CaseTypeFamilyID equals ctf.CaseTypeFamilyID + join ctfv in CaseTypeFamilyVersions on ctfmc.CaseTypeFamilyVersionID equals ctfv.CaseTypeFamilyVersionID + select new { ctfmc.CPTCode, ctf.CaseTypeFamilyID, ctf.Name }; + +var missing = from op in opcptcodes + join db in dbResults on op.CPTCode equals db.CPTCode into joined + from j in joined.DefaultIfEmpty() + where j == null || + (j != null && op.CaseTypeFamily != j.Name) + select new + { + op.CPTCode, + NewName = op.CaseTypeFamily, + OldCaseTypeFamilyID = j?.CaseTypeFamilyID ?? -1, + OldName = j?.Name ?? "" + }; + +var updates = from m in missing + join ctf in CaseTypeFamilies on m.NewName equals ctf.Name into joined + from j in joined.DefaultIfEmpty() + select new + { + m.CPTCode, + m.NewName, + NewCaseTypeFamilyID = j?.CaseTypeFamilyID ?? -1, + m.OldCaseTypeFamilyID, + m.OldName + }; + +updates +.Where(u => u.NewCaseTypeFamilyID != -1) +.OrderBy(u => u.NewCaseTypeFamilyID) +.Dump(nameof(updates)); + +updates +.Where(u => u.NewCaseTypeFamilyID == -1) +.Count().Dump("Count"); + +updates +.Where(u => u.NewCaseTypeFamilyID == -1) +.OrderBy(u => u.NewCaseTypeFamilyID) +.Dump("New Case Type Family"); + +var oldCaseTypeFamilies = updates +.Where(u => u.NewCaseTypeFamilyID != -1) +.Select(u => u.NewName).Distinct().OrderBy(u => u); +oldCaseTypeFamilies.Dump(nameof(oldCaseTypeFamilies)); + +var newCaseTypeFamilies = updates +.Where(u => u.NewCaseTypeFamilyID == -1) +.Select(u => u.NewName).Distinct().OrderBy(u => u); +newCaseTypeFamilies.Dump(nameof(newCaseTypeFamilies)); +*/ \ No newline at end of file diff --git a/CrossDB Missing StarterSet Definitions.linq b/CrossDB Missing StarterSet Definitions.linq new file mode 100644 index 0000000..6e01d1d --- /dev/null +++ b/CrossDB Missing StarterSet Definitions.linq @@ -0,0 +1,527 @@ + + + db640701-a1c5-4177-9f03-5152d093ffa7 + true + D0011-sql-01.sdt.local + jazz tst StrataSphere 20191104.1 + true + + RestSharp + RestSharp + Newtonsoft.Json + System.Data.Common + + +private string BaseUrl = "https://localhost:44325/api/v1/"; //"https://api-dev.sdt.local/starterset-api/api/v1/"; //"https://starterset-api.dev.k8s.sdt.local/api/v1/"; +private List TheGrade = new List(); + +#region *** Enumerations *** + +public enum QueryRegions +{ + Production, + Training, + Oak, + Dev +} + +#endregion + +#region *** Options *** + +public static QueryRegions queryRegion = QueryRegions.Dev; +public static string crossDBQueryPath = @"D:\CrossDBQueries"; // This is the path to find the queries +public static bool dumpOptions = false; // This flag will dumpt this set of options +public static bool dumpSmcSql = false; // This flag will dump the smc sql to the result +public static bool dumpDBList = false; // This flag will dump the databases to the result +public static bool dumpQueries = false; // This flag will dump the queries to the result +public static bool dumpDBExclusions = false; // This flag will dump the db and server exclusions +public static bool dumpDBTargets = false; // This flag will dump the db and server targets +public static bool dumpAppVersions = false; // This flag will dump the app versions used in the queryRegion +public static bool dumpAppVersionTargets = false; // This flag will dump the app versions targets +public static bool excludeExceptions = true; +public static bool queryCompress = false; +public static bool flatten = true; // This will flatten all of the results into a single list +public static bool showStopWatch = false; +public static bool noQueries = false; // This will stop the CrossDBQuery without running the queries + +#endregion + +public static Parms parms = new Parms +{ + name = "FY2020" +}; + +#region *** Database Selection *** + +public static string[] appVersions = { // This is a list of appVersions to filter for in the database list + //"2019.42" +}; + +public static string[] serverExclusions = { // This is a list of servers to exclude from the database list + @"paonsql19.sdt.local\instance1", + @"paonsql17.sdt.local\instance1", + @"p0555-sql-01.sdt.local\instance1", + "P0000-sql-01.sdt.local", + "P9900-SQL-03.sdt.local", + "P9900-sql-05.sdt.local" +}; + +public static string[] dbExclusions = { // This is a list of database physical names to exclude from the database list +}; +public static string[] targetOrgPins = { // This is a list of org pins to target in the database list +}; +public static string[] targetServers = { // This is a list of servers to target in the database list +}; +public static string[] targetDBs = { // This is a list of database physicial names to target in the database list +//"jazz tst Aultman 20200417.1" +}; + +#endregion *** Options *** + +#region *** SMC Settings and queries *** + +public static string smcSql => @"SELECT di.ServerName, di.DatabaseGUID, di.DatabaseName, di.PhysicalName, di.OrgPin, di.AppVersion, di.Description +FROM [dbo].[viewDatabaseInfo] di +WHERE 1=1" ++ (queryRegion == QueryRegions.Dev +? @" + AND di.PhysicalName like 'jazz%'" +: $@" + AND di.PhysicalName like 'jazz {(queryRegion != QueryRegions.Production ? "tst" : "prd")}%' + AND di.ServerName like 'p%'"); +public static string smcServer { get; set; } +public static string smcDB { get; set; } + +#endregion + +#region *** Program variables and settings *** + +public static IOrderedEnumerable databases => GetDatabases(); + +#endregion + +public void OptionsDump() +{ + var options = new + { + queryRegion, + crossDBQueryPath, + dumpOptions, + dumpSmcSql, + dumpDBList, + dumpQueries, + dumpDBExclusions, + dumpDBTargets, + dumpAppVersions, + dumpAppVersionTargets, + excludeExceptions, + queryCompress, + flatten, + showStopWatch, + noQueries + }; + options.Dump(nameof(options)); +} + +public class Parms +{ + public string name { get; set; } +} + +void Main() +{ + RestClient client = new RestClient(); + var definitions = GetList(client, "Definitions"); + var definitionTranslations = GetList(client, "DefinitionTranslations"); + + var work = definitions + .GroupBy(d => new + { + d.HierarchyGuid, + d.DimensionGuid, + d.AttributeGuid, + d.HierarchyId, + d.DimensionId, + d.AttributeId + }, (g, d) => new WorkDto + { + DefinitionGuids = d.Select(x => x.Id).ToList(), + HierarchyGuid = g.HierarchyGuid, + DimensionGuid = g.DimensionGuid, + AttributeGuid = g.AttributeGuid, + HierarchyId = g.HierarchyId, + DimensionId = g.DimensionId, + AttributeId = g.AttributeId, + Name = g.AttributeId == "a177cc88-e329-44e0-9063-2d9b59af51b2" + ? "Department" + : g.AttributeId == "f23654b3-149f-490a-a366-fca35f57d66a" + ? "EntityID" + : g.AttributeId == "MRDEPTENTITY" + ? "Entity" + : string.Empty + }) + .Distinct() + .OrderBy(d => d.DimensionId) + .ThenBy(d => d.AttributeId) + .ToList(); + + DoTheDumping(); + + databases + //.Where(d => d.DatabaseName == "Aultman") + .OrderBy(d => d.DatabaseName) + .ThenBy(d => d.OrgPin) + .ThenBy(d => d.PhysicalName) + .ToList() + .ForEach(db => + { + FindMissing(work, db); + }); + var theWork = TheGrade + .Distinct().ToList(); + //theWork.Dump(nameof(theWork)); + theWork.RemoveAll(tg => tg.AttributeGUID == Guid.Empty || tg.AttributeId == tg.AttributeGUID.ToString()); + JsonConvert.SerializeObject(theWork, Newtonsoft.Json.Formatting.Indented).Dump("json"); +} + +public void FindMissing(List work, Database database) +{ + var db = new TypedDataContext(database.ConnectionString); + try + { + var dimensions = work.Select(w => w.DimensionGuid).Distinct(); + var Score = + (from d in db.ScoreDimensions + join dg in db.ScoreDimensionGroups on d.DimensionGUID equals dg.DimensionGUID + join a in db.ScoreAttributes on dg.DimensionGroupGUID equals a.DimensionGroupGUID + where dimensions.Contains(d.DimensionGUID) + select new ScoreInfo(database.DatabaseName, database.DatabaseGuid, d.FriendlyName, d.DefaultHierarchyGUID, d.DimensionGUID, a.FriendlyName, a.AttributeGUID)) + .ToList(); + work.ToList() + .ForEach(w => + { + var scores = Score.Where(sw => sw.DimensionGUID == w.DimensionGuid).ToList(); + if (!scores.Any()) + return; + var s = scores.FirstOrDefault(sw => sw.AttributeGUID == w.AttributeGuid); + if (s != null) + { + w.score = s; + return; + } + s = scores.FirstOrDefault(sw => sw.AttributeName == w.Name); + if (s == null) + { + w.score = scores.FirstOrDefault(); + } + w.ByName = true; + w.score = s; + }); + var missing = work.Where(w => w.score == null || w.ByName).ToList(); + missing.ForEach(m => + { + if (m.score == null) + m.score = new ScoreInfo(database.DatabaseName, database.DatabaseGuid, "", Guid.Empty, Guid.Empty, "", Guid.Empty); + m.score.DefinitionGuids = new List(); + m.score.DefinitionGuids.AddRange(m.DefinitionGuids ?? new List()); + }); + var grades = missing.SelectMany(m => m.score.DefinitionGuids + .Select(dg => new DefinitionTranslationDto(dg, m.score.DatabaseName, m.score.DatabaseGuid, m.AttributeId, m.score.AttributeName, m.score.AttributeGUID))); + + TheGrade.AddRange(grades); + //missing.Dump(database.DatabaseName); + } + catch (Exception e) + { + + } + +} + +[JsonObject(MemberSerialization.OptIn)] +public class DefinitionTranslationDto +{ + [JsonProperty] + public Guid DefinitionId { get; set; } + public string DatabaseName { get; set; } + [JsonProperty] + public Guid DatabaseGuid { get; set; } + public string AttributeId { get; set; } + public string AttributeName {get;set;} + [JsonProperty] + public Guid AttributeGUID { get; set; } + + public DefinitionTranslationDto(Guid definitionId, string databaseName, Guid databaseGuid, string attributeId, string attributeName, Guid attributeGuid) + { + DefinitionId = definitionId; + DatabaseName = databaseName; + DatabaseGuid = databaseGuid; + AttributeId = attributeId; + AttributeName = attributeName; + AttributeGUID = attributeGuid; + } +} + +public class ScoreInfo +{ + public string DatabaseName { get; set; } + public Guid DatabaseGuid { get; set; } + public string DimensionName { get; set; } + public Guid HierarchyGUID { get; set; } + public Guid DimensionGUID { get; set; } + public string AttributeName { get; set; } + public Guid AttributeGUID { get; set; } + public List DefinitionGuids { get; set; } = new List(); + + public ScoreInfo(string databaseName, Guid databaseGuid, string dimensionName, Guid hierarchyGUID, Guid dimensionGUID, string attributeName, Guid attributeGUID) + { + DatabaseName = databaseName; + DatabaseGuid = databaseGuid; + DimensionName = dimensionName; + HierarchyGUID = hierarchyGUID; + DimensionGUID = dimensionGUID; + AttributeName = attributeName; + AttributeGUID = attributeGUID; + } + +} + +public class WorkDto +{ + public Guid HierarchyGuid { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string HierarchyId { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public string Name { get; set; } + public List DefinitionGuids { get; set; } + public bool ByName { get; set; } = false; + public ScoreInfo score { get; set; } +} + +public void DumpScore() +{ + var Score = + (from d in ScoreDimensions + join dg in ScoreDimensionGroups on d.DimensionGUID equals dg.DimensionGUID + join a in ScoreAttributes on dg.DimensionGroupGUID equals a.DimensionGroupGUID + select new { DimensionName = d.FriendlyName, d.DefaultHierarchyGUID, d.DimensionGUID, AttributeName = a.FriendlyName, a.AttributeGUID }); + + Score + .GroupBy(sdm => new { sdm.DimensionName, sdm.DefaultHierarchyGUID, sdm.DimensionGUID }, (g, d) => new + { + Dimension = new + { + g.DimensionName, + g.DimensionGUID, + g.DefaultHierarchyGUID, + Attributes = d.Count() + }, + Attributes = d.Select(sdm => new + { + sdm.AttributeName, + sdm.AttributeGUID + }) + .OrderBy(sdm => sdm.AttributeName) + .ToList() + }) + .OrderBy(ss => ss.Dimension.DimensionName) + .Dump(); +} + +// Define other methods and classes here + +#region *** Other classes *** + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +public class DefinitionDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public Guid HierarchyGuid { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string HierarchyId { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + + public DefinitionDto() + { + } +} + +public class Database +{ + public string Server { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string PhysicalName { get; set; } + public string OrgPin { get; set; } + public string AppVersion { get; set; } + public string Description { get; set; } + public Dictionary Fields { get; set; } + public string ConnectionString { get; set; } + + public Database() + { + + } + + public Database(DataRow dr) + { + Server = dr.Field("ServerName"); + DatabaseGuid = dr.Field("DatabaseGuid"); + DatabaseName = dr.Field("DatabaseName"); + PhysicalName = dr.Field("PhysicalName"); + OrgPin = dr.Field("OrgPin"); + AppVersion = dr.Field("AppVersion"); + Description = dr.Field("Description"); + Fields = new Dictionary(); + foreach (DataColumn column in dr.Table.Columns) + { + var index = dr.Table.Columns.IndexOf(column); + Fields.Add(column.ColumnName, dr[index].ToString()); + } + ConnectionString = BuildConnectionString(Server, PhysicalName); + } + + object ToDump() => (object)new + { + //Server, + //DatabaseGuid, + DatabaseName, + //PhysicalName, + //OrgPin, + //AppVersion, + //Description, + ConnectionString + }; +} + +#endregion + +#region *** Other methods here *** + +public void DoTheDumping() +{ + if (dumpOptions) + { + OptionsDump(); + } + if (dumpDBExclusions) + { + dbExclusions.Dump(nameof(dbExclusions)); + serverExclusions.Dump(nameof(serverExclusions)); + } + if (dumpDBTargets) + { + targetOrgPins.Dump(nameof(targetOrgPins)); + targetDBs.Dump(nameof(targetDBs)); + targetServers.Dump(nameof(targetServers)); + } + if (dumpAppVersionTargets) + { + appVersions.Dump(nameof(appVersions)); + } + if (dumpDBList) + { + databases.OrderBy(d => d.Server).ThenBy(d => d.PhysicalName).Dump($"{queryRegion} {nameof(databases)}"); + } + if (dumpAppVersions) + { + databases + .GroupBy(db => db.AppVersion, (grp, data) => data.Select(x => x.AppVersion).First()) + .OrderByDescending(db => db) + .Dump($"{queryRegion} {nameof(appVersions)}"); + } +} + +public static IOrderedEnumerable GetDatabases() +{ + switch (queryRegion) + { + case QueryRegions.Production: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc prod"; + break; + case QueryRegions.Training: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc training"; + break; + case QueryRegions.Oak: + smcServer = "ioak-sql-smc-01.sdt.local"; + smcDB = "smc qa"; + break; + default: + smcServer = "DDEN-SQL-SMC-01.sdt.local"; + smcDB = "smc dev"; + break; + } + if (dumpSmcSql) smcSql.Dump(nameof(smcSql)); + List databases = new List(); + var connStr = BuildConnectionString(smcServer, smcDB); + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(smcSql, conn); + command.CommandType = CommandType.Text; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var table = new DataTable(); + database.Tables.Add(table); + table.Load(reader); + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + databases = database.Tables[0].AsEnumerable().Select(dr => new Database(dr)).ToList(); + databases = databases.Where(dr => !dbExclusions.Contains(dr.PhysicalName) && !serverExclusions.Contains(dr.Server)).ToList(); + if (targetOrgPins.Any()) + databases = databases.Where(dr => targetOrgPins.Contains(dr.OrgPin)).ToList(); + if (targetServers.Any()) + databases = databases.Where(dr => targetServers.Contains(dr.Server)).ToList(); + if (targetDBs.Any()) + databases = databases.Where(dr => targetDBs.Contains(dr.PhysicalName)).ToList(); + if (appVersions.Any()) + databases = databases.Where(dr => appVersions.Contains(dr.AppVersion)).ToList(); + } + return databases + .OrderBy(d => d.Server).ThenBy(d => d.PhysicalName); +} + +public static string BuildConnectionString(string server, string database, string username = null, string password = null) +{ + return username == null + ? $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;" + : $"data source={server};initial catalog='{database}';User ID={username};pwd={password}"; +} + +#endregion \ No newline at end of file diff --git a/CrossDBQuery AppVersions.linq b/CrossDBQuery AppVersions.linq new file mode 100644 index 0000000..05c6185 --- /dev/null +++ b/CrossDBQuery AppVersions.linq @@ -0,0 +1,382 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.IO.Compression + System.Threading.Tasks + + +#region *** Enumerations *** + +public enum QueryRegions +{ + Production, + Training, + Oak, + Dev +} + +#endregion + +#region *** Options *** + +public static string crossDBQueryPath = @"D:\CrossDBQueries"; +public static QueryRegions queryRegion = QueryRegions.Production; +public static bool dumpSmcSql = false; +public static bool dumpDBList = true; +public static bool dumpQueries = false; +public static string[] appVersions = { + +}; +public static string[] serverExclusions = { + @"paonsql19.sdt.local\instance1", + @"paonsql17.sdt.local\instance1", + @"p0555-sql-01.sdt.local\instance1", + "P0000-sql-01.sdt.local", + "P9900-SQL-03.sdt.local", + "P9900-sql-05.sdt.local" +}; +public static string[] targetServers = { +}; +public static string[] targetDBs = { + //"jazz prd Gillette Childrens 20150417.1" + //"jazz prd Southern Illinois 20140408.1" + //"jazz tst Southern Illinois 20190918.1" + //"jazz dev master Prod" +}; +#endregion *** Options *** + +#region *** SMC Settings and queries *** + +public static string smcSql => @"SELECT di.ServerName, di.DatabaseGUID, di.DatabaseName, di.PhysicalName, di.OrgPin, di.AppVersion, di.Description +FROM [dbo].[viewDatabaseInfo] di +WHERE 1=1" ++ (queryRegion == QueryRegions.Dev +? @" + AND di.PhysicalName like 'jazz%'" +: $@" + AND di.PhysicalName like 'jazz {(queryRegion != QueryRegions.Production ? "tst" : "prd")}%' + AND di.ServerName like 'p%'") ++ (serverExclusions.Any() +? $@" + AND di.ServerName not in ('{string.Join("', '", serverExclusions)}')" +: "") ++ (targetServers.Any() +? $@" + AND di.ServerName in ('{string.Join("', '", targetServers)}')" +: "") ++ (targetDBs.Any() +? $@" + AND di.PhysicalName IN ('{string.Join(", '", targetDBs)}') +" +: "") ++ (appVersions.Any() +? $@" + AND di.AppVersion in ('{string.Join("', '", appVersions)}')" +: ""); +public static string smcServer { get; set; } +public static string smcDB { get; set; } + +#endregion + +#region *** Program variables and settings *** + +public static int maxThreads = 8; +public static int timeoutInMinutes = 2; +public static IList crossDBQueryResults = new List(); +public static IOrderedEnumerable databases => GetDatabases(); + +#endregion + +void Main() +{ + databases + .GroupBy(db => db.AppVersion, (grp, data) => data.Select(x => x.AppVersion).First()) + .OrderByDescending(db => db) + .Dump("AppVersions"); + /* + databases + .Select(db => new + { + db.AppVersion, + db.PhysicalName, + OrgPin = $"'{db.OrgPin}'" }) + .Where(db => db.AppVersion != "2019.43") + .OrderByDescending(db => db.AppVersion) + .ThenBy(db => db.OrgPin) + .Dump("AppVersions"); + */ + + // ExecuteCrossDBQueries() +// //.Where(r => !r.Exceptions.Any() && (r.Results.First().Results.First().Count() != 2).Any()) +// .OrderBy(dbqr => dbqr.Results.Any() ? 0 : 1) +// .ThenBy(dbqr => dbqr.Database.DatabaseName).Dump(nameof(crossDBQueryResults)); +} + +#region *** Other classes *** + +public class CrossDBQueryResult +{ + public Database Database { get; set; } + public List Results { get; set; } + public List Exceptions { get; set; } + public CrossDBQueryResult() + { + Results = new List(); + Exceptions = new List(); + } + + public CrossDBQueryResult(Database database, string name, IEnumerable enumerable) + : this() + { + Database = database; + Results.Add(new SqlResults(name, enumerable)); + } + + public CrossDBQueryResult(Database database, Exception exception) + : this() + { + Database = database; + Exceptions.Add(exception.ExceptionMessage()); + } + + object ToDump() => Exceptions.Any() ? (object)new + { + Database, + Results, + Exceptions + } : new + { + Database, + Results + }; +} + +public class SqlResults +{ + public string Name { get; set; } + public IEnumerable Results { get; set; } + public SqlResults(string name, IEnumerable results) + { + Name = name; + Results = results; + } +} + +public static class ExceptionExtension +{ + public static string ExceptionMessage(this Exception exception) + { + return $@"{exception.Message}{(exception.InnerException != null + ? $@" + {"".PadLeft(40, '-')} + {exception.InnerException.ExceptionMessage()}" + : "")}"; + } +} + +public class Database +{ + public string Server { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string PhysicalName { get; set; } + public string OrgPin { get; set; } + public string AppVersion { get; set; } + public string Description { get; set; } + + public Database() + { + + } + + public Database(DataRow dr) + { + Server = dr.Field("ServerName"); + DatabaseGuid = dr.Field("DatabaseGuid"); + DatabaseName = dr.Field("DatabaseName"); + PhysicalName = dr.Field("PhysicalName"); + OrgPin = dr.Field("OrgPin"); + AppVersion = dr.Field("AppVersion"); + Description = dr.Field("Description"); + } +} + +public class ThreadWithState +{ + private string connectionString => BuildConnectionString(_server, _databaseName); + private Database _database; + private string _server => _database?.Server ?? string.Empty; + private string _databaseName => _database?.PhysicalName ?? string.Empty; + private string sqlName; + private IEnumerable _sqlQueries; + + public ThreadWithState(Database database, KeyValuePair> sqlqueries) + { + _database = database; + sqlName = sqlqueries.Key; + _sqlQueries = sqlqueries.Value; + } + + public void ThreadProc() + { + var crossDB = crossDBQueryResults.FirstOrDefault(x => x.Database == _database); + IEnumerable ThreadResults; + foreach (var sqlQuery in _sqlQueries) + { + try + { + ThreadResults = SelectDynamic(connectionString, sqlQuery); + var result = ThreadResults.First(); + if (crossDB != null) + { + crossDB.Results.Add(new SqlResults(sqlName, ThreadResults)); + } + else + { + crossDB = new CrossDBQueryResult(_database, sqlName, ThreadResults); + crossDBQueryResults.Add(crossDB); + } + } + catch (Exception ex) + { + if (crossDB != null) + { + crossDB.Exceptions.Add(new Exception(sqlQuery, ex).ExceptionMessage()); + } + else + { + crossDBQueryResults.Add(new CrossDBQueryResult(_database, new Exception(sqlQuery, ex))); + } + } + } + } +} + +#endregion + +#region *** Other methods here *** + +public static IOrderedEnumerable GetDatabases() +{ + switch (queryRegion) + { + case QueryRegions.Production: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc prod"; + break; + case QueryRegions.Training: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc training"; + break; + case QueryRegions.Oak: + smcServer = "ioak-sql-smc-01.sdt.local"; + smcDB = "smc qa"; + break; + default: + smcServer = "DDEN-SQL-SMC-01.sdt.local"; + smcDB = "smc dev"; + break; + } + if (dumpSmcSql) smcSql.Dump(nameof(smcSql)); + IEnumerable dbInfos = new List(); + var connStr = BuildConnectionString(smcServer, smcDB); + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + var command = new SqlCommand(smcSql, conn); + command.CommandType = CommandType.Text; + var table = new DataTable(); + using (SqlDataReader reader = command.ExecuteReader()) + { + table.BeginLoadData(); + table.Load(reader); + table.EndLoadData(); + conn.Close(); + } + dbInfos = table.AsEnumerable().Select(dr => new Database(dr)); + } + return dbInfos + .OrderBy(d => d.Server).ThenBy(d => d.PhysicalName); +} + +public Dictionary> GetUserQueries(string path = null) +{ + var grp = 0; + return Directory.GetFiles(path ?? Directory.GetCurrentDirectory(), "*.sql", SearchOption.TopDirectoryOnly) + .ToDictionary(d => Path.GetFileNameWithoutExtension(d), f => File.ReadAllLines(f) + .Select(r => + { + if (r.Equals("go", StringComparison.CurrentCultureIgnoreCase)) + { + r = ""; + return new { grp = grp++, r }; + } + else + { + return new { grp, r }; + } + }).GroupBy(r => r.grp, (x, lines) => string.Join(" ", lines.Select(l => l.r).Where(l => !string.IsNullOrEmpty(l))))); +} + +public static IEnumerable SelectDynamic(string connStr, string sql) +{ + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + var command = new SqlCommand(sql, conn); + command.CommandType = CommandType.Text; + command.CommandTimeout = (int)TimeSpan.FromMinutes(timeoutInMinutes).TotalSeconds; + using (var reader = command.ExecuteReader()) + { + var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); + foreach (IDataRecord record in reader as IEnumerable) + { + var expando = new ExpandoObject() as IDictionary; + foreach (var name in names) + expando[name] = record[name]; + + yield return expando; + } + } + conn.Close(); + } +} + +public IList ExecuteCrossDBQueries() +{ + if (dumpDBList) databases.Dump(nameof(databases)); + var queries = GetUserQueries(crossDBQueryPath); + if (dumpQueries) queries.Dump(nameof(queries)); + RunCrossDBQuery(databases, queries); + return crossDBQueryResults; +} + +public void RunCrossDBQuery(IEnumerable databases, Dictionary> sqlList) +{ + var stopWatch = DateTime.Now; + var query = databases.AsParallel() + .SelectMany(database => sqlList.Where(sql => sql.Value.Any()).AsParallel() + .Select(sql => new ThreadWithState(database, sql))); + foreach (var q in query) + { + q.ThreadProc(); + } + DateTime.Now.Subtract(stopWatch).TotalSeconds.Dump(nameof(stopWatch)); +} + +public static string BuildConnectionString(string server, string database, string username = null, string password = null) +{ + return username == null + ? $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;" + : $"data source={server};initial catalog='{database}';User ID={username};pwd={password}"; +} + +#endregion \ No newline at end of file diff --git a/CrossDBQuery with useParms.linq b/CrossDBQuery with useParms.linq new file mode 100644 index 0000000..e65ac37 --- /dev/null +++ b/CrossDBQuery with useParms.linq @@ -0,0 +1,484 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.IO.Compression + System.Threading.Tasks + System.Data.Common + + +#region *** Enumerations *** + +public enum QueryRegions +{ + Production, + Training, + Oak, + Dev +} + +#endregion + +#region *** Options *** + +public static QueryRegions queryRegion = QueryRegions.Production; +public static string crossDBQueryPath = @"D:\CrossDBQueries"; // This is the path to find the queries +public static bool dumpSmcSql = false; // This flag will dump the smc sql to the result +public static bool dumpDBList = false; // This flag will dump the databases to the result +public static bool dumpQueries = true; // This flag will dump the queries to the result +public static bool dumpDBExclusions = false; // This flag will dump the db and server exclusions +public static bool dumpDBTargets = false; // This flag will dump the db and server targets +public static bool dumpAppVersions = false; // This flag will dump the app versions used in the queryRegion +public static bool dumpAppVersionTargets = false; // This flag will dump the app versions targets +public static bool excludeExceptions = true; +public static bool queryCompress = false; +public static bool flatten = true; // This will flatten all of the results into a single list +public static bool showStopWatch = false; +public static bool noQueries = false; // This will stop the CrossDBQuery without running the queries +public static bool useParms = true; + +#endregion + +public static Parms parms = new Parms +{ + name = "FY2020" +}; + +#region *** Database Selection *** + +public static string[] appVersions = { // This is a list of appVersions to filter for in the database list + //"2019.42" +}; +public static string[] serverExclusions = { // This is a list of servers to exclude from the database list + @"paonsql19.sdt.local\instance1", + @"paonsql17.sdt.local\instance1", + @"p0555-sql-01.sdt.local\instance1", + "P0000-sql-01.sdt.local", + "P9900-SQL-03.sdt.local", + "P9900-sql-05.sdt.local" +}; +public static string[] dbExclusions = { // This is a list of database physical names to exclude from the database list +// "jazz tst Team AP Training 01", +// "jazz tst Team AP Training 02", +// "jazz tst Team AP Training 11", +// "jazz tst Team AP Training 12", +// "jazz tst Team AP Training 13", +// "jazz tst Team AP Training 14" +}; +public static string[] targetOrgPins = { // This is a list of org pins to target in the database list +}; +public static string[] targetServers = { // This is a list of servers to target in the database list +// "P9900-SQL-11.sdt.local" +}; +public static string[] targetDBs = { // This is a list of database physicial names to target in the database list +// "jazz prd Gillette Childrens 20150417.1" +// "jazz prd Southern Illinois 20140408.1" +// "jazz tst Southern Illinois 20190918.1" +// "jazz dev master Prod" +}; + +#endregion *** Options *** + +#region *** SMC Settings and queries *** + +public static string smcSql => @"SELECT di.ServerName, di.DatabaseGUID, di.DatabaseName, di.PhysicalName, di.OrgPin, di.AppVersion, di.Description +FROM [dbo].[viewDatabaseInfo] di +WHERE 1=1" ++ (queryRegion == QueryRegions.Dev +? @" + AND di.PhysicalName like 'jazz%'" +: $@" + AND di.PhysicalName like 'jazz {(queryRegion != QueryRegions.Production ? "tst" : "prd")}%' + AND di.ServerName like 'p%'"); +public static string smcServer { get; set; } +public static string smcDB { get; set; } + +#endregion + +#region *** Program variables and settings *** + +public static int maxThreads = 8; +public static int timeoutInMinutes = 2; +public static IList crossDBQueryResults = new List(); +public static IOrderedEnumerable databases => GetDatabases(); +public static Dictionary> queries = System.IO.Directory.Exists(crossDBQueryPath) + ? GetUserQueries(crossDBQueryPath) + : new Dictionary>(); + +#endregion + +void Main() +{ + if (dumpDBExclusions) + { + dbExclusions.Dump(nameof(dbExclusions)); + serverExclusions.Dump(nameof(serverExclusions)); + } + if (dumpDBTargets) + { + targetOrgPins.Dump(nameof(targetOrgPins)); + targetDBs.Dump(nameof(targetDBs)); + targetServers.Dump(nameof(targetServers)); + } + if (dumpAppVersionTargets) + { + appVersions.Dump(nameof(appVersions)); + } + if (dumpDBList) + { + databases.OrderBy(d => d.Server).ThenBy(d => d.PhysicalName).Dump($"{queryRegion} {nameof(databases)}"); + } + if (dumpAppVersions) + { + databases + .GroupBy(db => db.AppVersion, (grp, data) => data.Select(x => x.AppVersion).First()) + .OrderByDescending(db => db) + .Dump($"{queryRegion} {nameof(appVersions)}"); + } + if (noQueries) return; + var results = ExecuteCrossDBQueries() + //.Where(r => !r.Exceptions.Any() && (r.Results.First().Results.First().Count() != 2).Any()) + //.Where(r => !r.Exceptions.Any() && r.Results.First().Name.Contains("Variation")) + .OrderBy(dbqr => dbqr.Results.Any() ? 0 : 1) + .ThenBy(dbqr => dbqr.Database.DatabaseName); + if (flatten) + { + results + .SelectMany(dbqr => dbqr.Results.SelectMany(r => r.Results).ToList()) + .Dump(nameof(crossDBQueryResults)); + } + else + { + results.Dump(nameof(crossDBQueryResults)); + } +} + +public class Parms +{ + public string name { get; set; } +} + +#region *** Other classes *** + +public class CrossDBQueryResultLite +{ + public Database Database { get; set; } + public List Results { get; set; } +} +public class CrossDBQueryResult : CrossDBQueryResultLite +{ + public List Exceptions { get; set; } + public CrossDBQueryResult() + { + Results = new List(); + Exceptions = new List(); + } + + public CrossDBQueryResult(Database database, string name, IEnumerable enumerable) + : this() + { + Database = database; + Results.Add(new SqlResults(name, enumerable)); + } + + public CrossDBQueryResult(Database database, Exception exception) + : this() + { + Database = database; + Exceptions.Add(exception.ExceptionMessage()); + } + + object ToDump() => excludeExceptions + ? (object)new + { + Database, + Results + } +: new +{ + Database, + Results, + Exceptions +}; +} + +public class SqlResults +{ + public string Name { get; set; } + public IEnumerable Results { get; set; } + public SqlResults(string name, IEnumerable results) + { + Name = name; + Results = results; + } +} + +public static class ExceptionExtension +{ + public static string ExceptionMessage(this Exception exception) + { + return $@"{exception.Message}{(exception.InnerException != null + ? $@" + {"".PadLeft(40, '-')} + {exception.InnerException.ExceptionMessage()}" + : "")}"; + } +} + +public class Database +{ + public string Server { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string PhysicalName { get; set; } + public string OrgPin { get; set; } + public string AppVersion { get; set; } + public string Description { get; set; } + public Dictionary Fields { get; set; } + + public Database() + { + + } + + public Database(DataRow dr) + { + Server = dr.Field("ServerName"); + DatabaseGuid = dr.Field("DatabaseGuid"); + DatabaseName = dr.Field("DatabaseName"); + PhysicalName = dr.Field("PhysicalName"); + OrgPin = dr.Field("OrgPin"); + AppVersion = dr.Field("AppVersion"); + Description = dr.Field("Description"); + Fields = new Dictionary(); + foreach (DataColumn column in dr.Table.Columns) + { + var index = dr.Table.Columns.IndexOf(column); + Fields.Add(column.ColumnName, dr[index].ToString()); + } + } + + object ToDump() => (object)new + { + Server, + DatabaseGuid, + DatabaseName, + PhysicalName, + OrgPin, + AppVersion, + Description + }; +} + +public class ThreadWithState +{ + private string connectionString => BuildConnectionString(_server, _databaseName); + private Database _database; + private string _server => _database?.Server ?? string.Empty; + private string _databaseName => _database?.PhysicalName ?? string.Empty; + private string sqlName; + private IEnumerable _sqlQueries; + + public ThreadWithState(Database database, KeyValuePair> sqlqueries) + { + _database = database; + sqlName = sqlqueries.Key; + _sqlQueries = sqlqueries.Value; + } + + public void ThreadProc() + { + var crossDB = crossDBQueryResults.FirstOrDefault(x => x.Database == _database); + IEnumerable ThreadResults; + foreach (var sqlQuery in _sqlQueries) + { + try + { + ThreadResults = SelectDynamic(_database, connectionString, sqlQuery); + var result = ThreadResults.First(); + if (crossDB != null) + { + crossDB.Results.Add(new SqlResults(sqlName, ThreadResults)); + } + else + { + crossDB = new CrossDBQueryResult(_database, sqlName, ThreadResults); + crossDBQueryResults.Add(crossDB); + } + } + catch (Exception ex) + { + if (crossDB != null) + { + crossDB.Exceptions.Add(new Exception(sqlQuery, ex).ExceptionMessage()); + } + else + { + crossDBQueryResults.Add(new CrossDBQueryResult(_database, new Exception(sqlQuery, ex))); + } + } + } + } +} + +#endregion + +#region *** Other methods here *** + +public static IOrderedEnumerable GetDatabases() +{ + switch (queryRegion) + { + case QueryRegions.Production: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc prod"; + break; + case QueryRegions.Training: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc training"; + break; + case QueryRegions.Oak: + smcServer = "ioak-sql-smc-01.sdt.local"; + smcDB = "smc qa"; + break; + default: + smcServer = "DDEN-SQL-SMC-01.sdt.local"; + smcDB = "smc dev"; + break; + } + if (dumpSmcSql) smcSql.Dump(nameof(smcSql)); + List databases = new List(); + var connStr = BuildConnectionString(smcServer, smcDB); + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(smcSql, conn); + command.CommandType = CommandType.Text; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var table = new DataTable(); + database.Tables.Add(table); + table.Load(reader); + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + databases = database.Tables[0].AsEnumerable().Select(dr => new Database(dr)).ToList(); + databases = databases.Where(dr => !dbExclusions.Contains(dr.PhysicalName) && !serverExclusions.Contains(dr.Server)).ToList(); + if (targetOrgPins.Any()) + databases = databases.Where(dr => targetOrgPins.Contains(dr.OrgPin)).ToList(); + if (targetServers.Any()) + databases = databases.Where(dr => targetServers.Contains(dr.Server)).ToList(); + if (targetDBs.Any()) + databases = databases.Where(dr => targetDBs.Contains(dr.PhysicalName)).ToList(); + if (appVersions.Any()) + databases = databases.Where(dr => appVersions.Contains(dr.AppVersion)).ToList(); + } + return databases + .OrderBy(d => d.Server).ThenBy(d => d.PhysicalName); +} + +public static Dictionary> GetUserQueries(string path = null) +{ + var grp = 0; + var queries = Directory.GetFiles(path ?? Directory.GetCurrentDirectory(), "*.sql", SearchOption.TopDirectoryOnly) + .ToDictionary(d => Path.GetFileNameWithoutExtension(d), f => File.ReadAllLines(f) + .Select(r => + { + if (r.Equals("go", StringComparison.CurrentCultureIgnoreCase)) + { + r = ""; + return new { grp = grp++, r }; + } + else + { + return new { grp, r }; + } + }).GroupBy(r => r.grp, (x, lines) => string.Join(queryCompress ? " " : "\r\n", lines.Select(l => l.r).Where(l => !string.IsNullOrEmpty(l))))); + + // foreach (var key in queries.Keys) + // { + // foreach (var query in queries[key]) + // { + // if (useParms) + // { + // FormattableString formatter = $""; + // string.Format(formatter, parms).Dump(); + // } + // } + // } + + if (dumpQueries) + queries.Dump(nameof(queries)); + return queries; +} + +public static IEnumerable SelectDynamic(Database db, string connStr, string sql) +{ + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(sql, conn); + command.CommandType = CommandType.Text; + command.CommandTimeout = (int)TimeSpan.FromMinutes(timeoutInMinutes).TotalSeconds; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); + foreach (IDataRecord record in reader as IEnumerable) + { + var expando = new ExpandoObject() as IDictionary; + if (flatten) + db.Fields.ForEach((x, y) => expando[x.Key] = x.Value); + foreach (var name in names) + expando[name] = record[name]; + + yield return expando; + } + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + } +} + +public IList ExecuteCrossDBQueries() +{ + RunCrossDBQuery(databases, queries); + return crossDBQueryResults; +} + +public void RunCrossDBQuery(IEnumerable databases, Dictionary> sqlList) +{ + var stopWatch = DateTime.Now; + var query = databases.AsParallel() + .SelectMany(database => sqlList.Where(sql => sql.Value.Any()).AsParallel() + .Select(sql => new ThreadWithState(database, sql))); + foreach (var q in query) + { + q.ThreadProc(); + } + var timer = DateTime.Now.Subtract(stopWatch).TotalSeconds; + if (showStopWatch) timer.Dump(nameof(stopWatch)); +} + +public static string BuildConnectionString(string server, string database, string username = null, string password = null) +{ + return username == null + ? $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;" + : $"data source={server};initial catalog='{database}';User ID={username};pwd={password}"; +} + +#endregion \ No newline at end of file diff --git a/CrossDBQuery.linq b/CrossDBQuery.linq new file mode 100644 index 0000000..567d2fc --- /dev/null +++ b/CrossDBQuery.linq @@ -0,0 +1,503 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.IO.Compression + System.Threading.Tasks + System.Data.Common + + +#region *** Enumerations *** + +public enum QueryRegions +{ + Production, + Training, + Oak, + Dev +} + +#endregion + +#region *** Options *** + +public static QueryRegions queryRegion = QueryRegions.Dev; +public static string crossDBQueryPath = @"C:\Users\tlamb\Documents\CrossDBQueries"; // This is the path to find the queries +public static bool checkForCILicensing = true; // This flag will add a column if the client db is licensed for CI +public static bool dumpOptions = false; // This flag will dumpt this set of options +public static bool dumpSmcSql = false; // This flag will dump the smc sql to the result +public static bool dumpDBList = false; // This flag will dump the databases to the result +public static bool dumpQueries = false; // This flag will dump the queries to the result +public static bool dumpDBExclusions = false; // This flag will dump the db and server exclusions +public static bool dumpDBTargets = false; // This flag will dump the db and server targets +public static bool dumpAppVersions = false; // This flag will dump the app versions used in the queryRegion +public static bool dumpAppVersionTargets = false; // This flag will dump the app versions targets +public static bool excludeExceptions = true; +public static bool queryCompress = false; +public static bool flatten = true; // This will flatten all of the results into a single list +public static bool showStopWatch = false; +public static bool noQueries = false; // This will stop the CrossDBQuery without running the queries + +#endregion + +public static Parms parms = new Parms +{ + name = "FY2020" +}; + +#region *** Database Selection *** + +public static string[] appVersions = { // This is a list of appVersions to filter for in the database list + //"2020.31" +}; +public static string[] serverExclusions = { // This is a list of servers to exclude from the database list + @"paonsql19.sdt.local\instance1", + @"paonsql17.sdt.local\instance1", + @"p0555-sql-01.sdt.local\instance1", + "P0000-sql-01.sdt.local", + "P9900-SQL-03.sdt.local", + "P9900-sql-05.sdt.local" +}; +public static string[] dbExclusions = { // This is a list of database physical names to exclude from the database list +}; +public static string[] targetOrgPins = { // This is a list of org pins to target in the database list +// "0430", "0434", "0555", "0777" +}; +public static string[] targetServers = { // This is a list of servers to target in the database list +// "P9900-SQL-11.sdt.local" +// "D0018-SQL-01.sdt.local" +}; +public static string[] targetDBs = { // This is a list of database physicial names to target in the database list +// "jazz prd Gillette Childrens 20150417.1" +// "jazz prd Southern Illinois 20140408.1" +// "jazz tst Southern Illinois 20190918.1" +// "jazz dev master Prod" +}; + +#endregion *** Options *** + +#region *** SMC Settings and queries *** + +public static string smcSql => $@"SELECT di.ServerName, di.DatabaseGUID, di.DatabaseName, di.PhysicalName, di.OrgPin, di.AppVersion, di.Description +{(checkForCILicensing ? " ,(select COUNT(*) from [dbo].[viewLicenseLink] l where l.NAME = 'ContinuousImprovement' and l.DatabaseGUID = di.DatabaseGUID and l.IsLicensed = 1) CI_LICENSED" : "")} +FROM [dbo].[viewDatabaseInfo] di +WHERE 1=1" ++ (queryRegion == QueryRegions.Dev +? @" + AND di.PhysicalName like 'jazz%'" +: $@" + AND di.PhysicalName like 'jazz {(queryRegion != QueryRegions.Production ? "tst" : "prd")}%' + AND di.ServerName like 'p%'"); +public static string smcServer { get; set; } +public static string smcDB { get; set; } + +#endregion + +#region *** Program variables and settings *** + +public static int maxThreads = 8; +public static int timeoutInMinutes = 2; +public static IList crossDBQueryResults = new List(); +public static IOrderedEnumerable databases => GetDatabases(); +public static Dictionary> queries = System.IO.Directory.Exists(crossDBQueryPath) + ? GetUserQueries(crossDBQueryPath) + : new Dictionary>(); + +#endregion + +void Main() +{ + if (dumpOptions) + { + OptionsDump(); + } + if (dumpDBExclusions) + { + dbExclusions.Dump(nameof(dbExclusions)); + serverExclusions.Dump(nameof(serverExclusions)); + } + if (dumpDBTargets) + { + targetOrgPins.Dump(nameof(targetOrgPins)); + targetDBs.Dump(nameof(targetDBs)); + targetServers.Dump(nameof(targetServers)); + } + if (dumpAppVersionTargets) + { + appVersions.Dump(nameof(appVersions)); + } + if (dumpDBList) + { + databases.OrderBy(d => d.Server).ThenBy(d => d.PhysicalName).Dump($"{queryRegion} {nameof(databases)}"); + } + if (dumpAppVersions) + { + databases + .GroupBy(db => db.AppVersion, (grp, data) => data.Select(x => x.AppVersion).First()) + .OrderByDescending(db => db) + .Dump($"{queryRegion} {nameof(appVersions)}"); + } + if (noQueries) return; + var results = ExecuteCrossDBQueries() + .OrderBy(dbqr => dbqr.Results.Any() ? 0 : 1) + .ThenBy(dbqr => dbqr.Database.DatabaseName); + if (flatten) + { + results + .SelectMany(dbqr => dbqr.Results.SelectMany(r => r.Results).ToList()) + .Where(dbqr => dbqr.CI_LICENSED == "1") + .GroupBy(dbqr => dbqr.DatabaseGUID, (g,d) => d.First()) + .Distinct() + .Dump(nameof(crossDBQueryResults)); + } + else + { + results.Dump(nameof(crossDBQueryResults)); + } +} + +public void OptionsDump() +{ + var options = new + { + queryRegion, + crossDBQueryPath, + dumpOptions, + dumpSmcSql, + dumpDBList, + dumpQueries, + dumpDBExclusions, + dumpDBTargets, + dumpAppVersions, + dumpAppVersionTargets, + excludeExceptions, + queryCompress, + flatten, + showStopWatch, + noQueries + }; + options.Dump(nameof(options)); +} + +public class Parms +{ + public string name { get; set; } +} + +#region *** Other classes *** + +public class CrossDBQueryResultLite +{ + public Database Database { get; set; } + public List Results { get; set; } +} +public class CrossDBQueryResult : CrossDBQueryResultLite +{ + public List Exceptions { get; set; } + public CrossDBQueryResult() + { + Results = new List(); + Exceptions = new List(); + } + + public CrossDBQueryResult(Database database, string name, IEnumerable enumerable) + : this() + { + Database = database; + Results.Add(new SqlResults(name, enumerable)); + } + + public CrossDBQueryResult(Database database, Exception exception) + : this() + { + Database = database; + Exceptions.Add(exception.ExceptionMessage()); + } + + object ToDump() => excludeExceptions + ? (object)new + { + Database, + Results + } +: new +{ + Database, + Results, + Exceptions +}; +} + +public class SqlResults +{ + public string Name { get; set; } + public IEnumerable Results { get; set; } + public SqlResults(string name, IEnumerable results) + { + Name = name; + Results = results; + } +} + +public static class ExceptionExtension +{ + public static string ExceptionMessage(this Exception exception) + { + return $@"{exception.Message}{(exception.InnerException != null + ? $@" + {"".PadLeft(40, '-')} + {exception.InnerException.ExceptionMessage()}" + : "")}"; + } +} + +public class Database +{ + public string Server { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string PhysicalName { get; set; } + public string OrgPin { get; set; } + public string AppVersion { get; set; } + public string Description { get; set; } + public Dictionary Fields { get; set; } + + public Database() + { + + } + + public Database(DataRow dr) + { + Server = dr.Field("ServerName"); + DatabaseGuid = dr.Field("DatabaseGuid"); + DatabaseName = dr.Field("DatabaseName"); + PhysicalName = dr.Field("PhysicalName"); + OrgPin = dr.Field("OrgPin"); + AppVersion = dr.Field("AppVersion"); + Description = dr.Field("Description"); + Fields = new Dictionary(); + foreach (DataColumn column in dr.Table.Columns) + { + var index = dr.Table.Columns.IndexOf(column); + Fields.Add(column.ColumnName, dr[index].ToString()); + } + } + + object ToDump() => (object)new + { + Server, + DatabaseGuid, + DatabaseName, + PhysicalName, + OrgPin, + AppVersion, + Description + }; +} + +public class ThreadWithState +{ + private string connectionString => BuildConnectionString(_server, _databaseName); + private Database _database; + private string _server => _database?.Server ?? string.Empty; + private string _databaseName => _database?.PhysicalName ?? string.Empty; + private string sqlName; + private IEnumerable _sqlQueries; + + public ThreadWithState(Database database, KeyValuePair> sqlqueries) + { + _database = database; + sqlName = sqlqueries.Key; + _sqlQueries = sqlqueries.Value; + } + + public void ThreadProc() + { + var crossDB = crossDBQueryResults.FirstOrDefault(x => x.Database == _database); + IEnumerable ThreadResults; + foreach (var sqlQuery in _sqlQueries) + { + try + { + ThreadResults = SelectDynamic(_database, connectionString, sqlQuery); + var result = ThreadResults.First(); + if (crossDB != null) + { + crossDB.Results.Add(new SqlResults(sqlName, ThreadResults)); + } + else + { + crossDB = new CrossDBQueryResult(_database, sqlName, ThreadResults); + crossDBQueryResults.Add(crossDB); + } + } + catch (Exception ex) + { + if (crossDB != null) + { + crossDB.Exceptions.Add(new Exception(sqlQuery, ex).ExceptionMessage()); + } + else + { + crossDBQueryResults.Add(new CrossDBQueryResult(_database, new Exception(sqlQuery, ex))); + } + } + } + } +} + +#endregion + +#region *** Other methods here *** + +public static IOrderedEnumerable GetDatabases() +{ + switch (queryRegion) + { + case QueryRegions.Production: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc prod"; + break; + case QueryRegions.Training: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc training"; + break; + case QueryRegions.Oak: + smcServer = "ioak-sql-smc-01.sdt.local"; + smcDB = "smc qa"; + break; + default: + smcServer = "DDEN-SQL-SMC-01.sdt.local"; + smcDB = "smc dev"; + break; + } + if (dumpSmcSql) smcSql.Dump(nameof(smcSql)); + List databases = new List(); + var connStr = BuildConnectionString(smcServer, smcDB); + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(smcSql, conn); + command.CommandType = CommandType.Text; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var table = new DataTable(); + database.Tables.Add(table); + table.Load(reader); + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + databases = database.Tables[0].AsEnumerable().Select(dr => new Database(dr)).ToList(); + databases = databases.Where(dr => !dbExclusions.Contains(dr.PhysicalName) && !serverExclusions.Contains(dr.Server)).ToList(); + if (targetOrgPins.Any()) + databases = databases.Where(dr => targetOrgPins.Contains(dr.OrgPin)).ToList(); + if (targetServers.Any()) + databases = databases.Where(dr => targetServers.Contains(dr.Server)).ToList(); + if (targetDBs.Any()) + databases = databases.Where(dr => targetDBs.Contains(dr.PhysicalName)).ToList(); + if (appVersions.Any()) + databases = databases.Where(dr => appVersions.Contains(dr.AppVersion)).ToList(); + } + return databases + .OrderBy(d => d.Server).ThenBy(d => d.PhysicalName); +} + +public static Dictionary> GetUserQueries(string path = null) +{ + var grp = 0; + var queries = Directory.GetFiles(path ?? Directory.GetCurrentDirectory(), "*.sql", SearchOption.TopDirectoryOnly) + .ToDictionary(d => Path.GetFileNameWithoutExtension(d), f => File.ReadAllLines(f) + .Select(r => + { + if (r.Equals("go", StringComparison.CurrentCultureIgnoreCase)) + { + r = ""; + return new { grp = grp++, r }; + } + else + { + return new { grp, r }; + } + }).GroupBy(r => r.grp, (x, lines) => string.Join(queryCompress ? " " : "\r\n", lines.Select(l => l.r).Where(l => !string.IsNullOrEmpty(l))))); + + if (dumpQueries) + queries.Dump(nameof(queries)); + return queries; +} + +public static IEnumerable SelectDynamic(Database db, string connStr, string sql) +{ + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(sql, conn); + command.CommandType = CommandType.Text; + command.CommandTimeout = (int)TimeSpan.FromMinutes(timeoutInMinutes).TotalSeconds; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); + foreach (IDataRecord record in reader as IEnumerable) + { + var expando = new ExpandoObject() as IDictionary; + if (flatten) + { + foreach (var field in db.Fields) + { + expando[field.Key] = field.Value; + } + } + foreach (var name in names) + expando[name] = record[name]; + + yield return expando; + } + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + } +} + +public IList ExecuteCrossDBQueries() +{ + RunCrossDBQuery(databases, queries); + return crossDBQueryResults; +} + +public void RunCrossDBQuery(IEnumerable databases, Dictionary> sqlList) +{ + var stopWatch = DateTime.Now; + var query = databases.AsParallel() + .SelectMany(database => sqlList.Where(sql => sql.Value.Any()).AsParallel() + .Select(sql => new ThreadWithState(database, sql))); + foreach (var q in query) + { + q.ThreadProc(); + } + var timer = DateTime.Now.Subtract(stopWatch).TotalSeconds; + if (showStopWatch) timer.Dump(nameof(stopWatch)); +} + +public static string BuildConnectionString(string server, string database, string username = null, string password = null) +{ + return username == null + ? $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;" + : $"data source={server};initial catalog='{database}';User ID={username};pwd={password}"; +} + +#endregion \ No newline at end of file diff --git a/CultureInfo with examples.linq b/CultureInfo with examples.linq new file mode 100644 index 0000000..b684de2 --- /dev/null +++ b/CultureInfo with examples.linq @@ -0,0 +1,205 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + <RuntimeDirectory>\System.ComponentModel.Composition.dll + <RuntimeDirectory>\System.ComponentModel.dll + <RuntimeDirectory>\System.Net.dll + <RuntimeDirectory>\System.Net.Http.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + TimeZoneNames + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.Globalization + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + TimeZoneNames + + +void Main() +{ + var currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; + // Get server DateTime. + DateTime date = DateTime.Now; + var amount = 12345.67M; + + // Get a list of all Cultures + List cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures) + //.Where(ci => ci.Name == "en-MW") + .ToList(); + + // Add the Cultures to an ArrayList so we can sort them Alphabetically by name. + List cultureList = new List(); + foreach (CultureInfo culture in cultures) + { + System.Threading.Thread.CurrentThread.CurrentCulture = culture; + RegionInfo regionInfo = default(RegionInfo); + if (culture.LCID != 4096 && !culture.Equals(CultureInfo.InvariantCulture)) + { + regionInfo = new RegionInfo(culture.LCID); + } + string pattern = null; + switch (culture.NumberFormat.CurrencyPositivePattern) + { + case 0: + pattern = "{0}{1:N" + culture.NumberFormat.CurrencyDecimalDigits + "}"; + break; + case 1: + pattern = "{1:N" + culture.NumberFormat.CurrencyDecimalDigits + "}{0}"; + break; + case 2: + pattern = "{0} {1:N" + culture.NumberFormat.CurrencyDecimalDigits + "}"; + break; + case 3: + pattern = "{1:N" + culture.NumberFormat.CurrencyDecimalDigits + "} {0}"; + break; + } + cultureList.Add(new CultureData + { + EnglishName = culture.EnglishName, + Name = culture.Name, + Details = new CultureDetails + { + ShortDate_Format = culture.DateTimeFormat.ShortDatePattern, + ShortDate_Example = date.ToShortDateString(), + LongDate_Format = culture.DateTimeFormat.LongDatePattern, + LongDate_Example = date.ToLongDateString(), + ShortTime_Format = culture.DateTimeFormat.ShortTimePattern, + ShortTime_Example = date.ToShortTimeString(), + LongTime_Format = culture.DateTimeFormat.LongTimePattern, + LongTime_Example = date.ToLongTimeString(), + Currency_EnglishName = regionInfo?.CurrencyEnglishName ?? string.Empty, + Currency_NativeName = regionInfo?.CurrencyNativeName ?? string.Empty, + Currency_Format = pattern, + Currency_Example = string.Format(culture, "{0:C}", amount), + Currency_ExampleNeg = string.Format(culture, "{0:C}", (amount * -1)), + Currency_ExampleAlt = string.Format(culture, "{0:c}", amount), + Currency_ExampleAltNeg = string.Format(culture, "{0:C}", (amount * -1)), + Percentage_Format = $"{{{culture.NumberFormat.PercentPositivePattern}{culture.NumberFormat.PercentDecimalSeparator}{culture.NumberFormat.PercentDecimalDigits}:P}}", + Percentage_Symbol = culture.NumberFormat.PercentSymbol, + Percentage_Example = string.Format(culture, "{0:P}", .333) + }, + MonthNames = MonthNames(culture), +// TimeZones = TimeZones(currentCulture) + }); + } + + // Sort Cultures + //cultureList.Sort(new StringComparer()); + cultureList + //.Where(l => l.Details.Percentage_Symbol != "%") + .OrderBy(c => c.EnglishName) + //.Where(c => c.EnglishName.Contains("Bermuda")) + .Dump(nameof(cultureList)); + + currentCulture = CultureInfo.GetCultures(CultureTypes.SpecificCultures).FirstOrDefault(c => c.EnglishName == "English (United States)"); + System.Threading.Thread.CurrentThread.CurrentCulture = currentCulture; + +} + +class CultureDetails +{ + public string ShortDate_Format { get; set; } + public string ShortDate_Example { get; set; } + public string LongDate_Format { get; set; } + public string LongDate_Example { get; set; } + public string ShortTime_Format { get; set; } + public string ShortTime_Example { get; set; } + public string LongTime_Format { get; set; } + public string LongTime_Example { get; set; } + public string Currency_EnglishName { get; set; } + public string Currency_NativeName { get; set; } + public string Currency_Format { get; set; } + public string Currency_Example { get; set; } + public string Currency_ExampleNeg { get; set; } + public string Currency_ExampleAlt { get; set; } + public string Currency_ExampleAltNeg { get; set; } + public string Percentage_Format { get; set; } + public string Percentage_Symbol { get; set; } + public string Percentage_Example { get; set; } +} +class CultureData +{ + public string EnglishName { get; set; } + public string Name { get; set; } + public IDictionary MonthNames { get; set; } + public CultureDetails Details { get; set; } + public IEnumerable TimeZones { get; set; } +} + +public IDictionary MonthNames(CultureInfo culture) +{ + return Enumerable.Range(1, 12).ToList() + .Select(mm => new { Key = mm, Value = culture.DateTimeFormat.GetMonthName(mm) }) + .ToDictionary(item => item.Key, item => item.Value); +} + +public IEnumerable TimeZones(CultureInfo culture) +{ + return TimeZoneInfo.GetSystemTimeZones(); +} + +public void TimeZoneList(CultureInfo culture) +{ + TimeZoneInfo.GetSystemTimeZones() + .SelectMany(tzi => new[] { + TZNames.GetAbbreviationsForTimeZone(tzi.Id, culture.Name).Daylight != TZNames.GetAbbreviationsForTimeZone(tzi.Id, culture.Name).Standard + ? new { Key = tzi.Id.Replace("Standard", "Daylight"), Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, culture.Name).Daylight } + : new { Key = tzi.Id, Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, culture.Name).Daylight }, + new { Key = tzi.Id, Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, culture.Name).Standard }}) + .GroupBy(x => x.Key) + .Select(g => g.First()) + .ToDictionary(item => item.Key, item => item.Value) + .OrderBy(item => item.Key) + .Dump(); +} \ No newline at end of file diff --git a/DB Query Exceptions.linq b/DB Query Exceptions.linq new file mode 100644 index 0000000..68ee169 --- /dev/null +++ b/DB Query Exceptions.linq @@ -0,0 +1,605 @@ + + + 580b3b8d-cc02-4a68-8fbd-d1ec374a25f2 + true + D0001-sql-11.sdt.local + jazz dev master Prod + true + + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Linq.Dynamic + + +// This link provides a good explanation of the Dynamic Query used in the DataTableJoins +// https://ecs.syr.edu/faculty/fawcett/handouts/CoreTechnologies/CSharp/samples/CSharpSamples/LinqSamples/DynamicQuery/Dynamic%20Expressions.html +// +#region Options + +public static int TopRows = 1000; //int.MaxValue; +public static int TableDumpDepth = int.MaxValue; //2; +public static bool ShowTableQuery = false; +public static bool ShowTablesToRemove = false; +public static bool ShowTableNames = false; +public static bool ShowTableList = false; +public static bool ShowMissingUpdate = true; +public static bool ShowMissingLegacy = false; + +#endregion + +private Connections connections = new Connections +{ + //Legacy = new ServerInstance("E0001-SQL-11.sdt.local", "StrataSphere"), + //Update = new ServerInstance("D0011-SQL-01.sdt.local", "StrataSphere") + Legacy = new ServerInstance("D0011-SQL-01.sdt.local", "jazz tst Southern Illinois 20190918.1"), + Update = new ServerInstance("D0011-SQL-01.sdt.local", "jazz tst Southern Illinois 20200331.1") + //Legacy = new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod 20190708.1"), + //Update = new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod") +}; +// Hints: +// 1) if you pass a null for the table list it will include all tables in the schema +// 2) if you pass a table name like "C%"' it will only include all tables that start with C +private List SchemasAndTablesToReview = new List { + new TablesAndColumns("cci", new[] {"%QVILineItemOpportunity%"}), + //new TablesAndColumns("clientdss", new [] { "FactPatientEncounterSummary" }), + //new TablesAndColumns("dss", new [] {"%CaseType%"}, new[] {"CaseTypeDRGMapping","CaseTypeFamilyMapping","FactCaseTypeMapping"}), + //new TablesAndColumns("fw", new []{ "DimAgeCohort"}) +}; + +void Main() +{ + var tables = GetTables().ToList(); + // Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + tables.ForEach(table => + { + switch (table.SchemaName) + { + case "cci": + switch (table.TableName) + { + case "ChargeCodeConfig": + table.Init( + new[] { "ChargeCodeID", "CostDriver" }, + keyColumns: new[] { "ChargeCodeID", "CostDriver" } + ); + break; + case "ChargeCodeCostDetail": + table.Init( + new[] { "EntityID", "ChargeCodeID" }, + keyColumns: new[] { "EntityID", "ChargeCodeID" } + ); + break; + case "Configuration": + table.Init(new[] { "D|FiscalYearID" }, new[] { "InitiativeIsSimplifiedWorkflow" }, new[] { "FiscalYearId" }); + break; + case "InitiativeWorkflowHistory": + table.Init(new[] { "FromStep", "ToStep" }); + break; + case "VariationEncounterSavingInfo": + table.Init(new[] { "EncounterRecordNumber" }); + break; + case "FactOpportunityMetric": + table.Init(new[] { "FiscalYearID", "FiscalMonthID" }); + break; + case "FactOpportunitySavings": + table.Init(new[] { "FiscalyYearID", "FiscalMonthID" }); + break; + case "Initiative": + table.Init(new[] { "Name" }); + break; + case "SystemSetting": + table.Excludes(new[] { "IsEncrypted" }); + break; + case "QVILineItemOpportunity": + table.KeyColumns(new[] {"BreakdownID", "QVILineItemID", "QualityVariationEventID"}); + break; + case "VariationOpportunity": + table.Init( + new[] { "CaseTypeEntityId", "CostDriver" }, + keyColumns: new[] { "CostDriver", "CastTypeEntityId" } + ); + break; + }; + break; + case "clientdss": + switch (table.TableName) + { + case "FactPatientEncounterSummary": + table.Init( + new[] { "EncounterRecordNumber" }, + new[] { "MikeQAtest1ID", "CustomJesseValidatingAllOthers", "CustomNewCalculatedSystemFieldasdf" }, + where: "OBJ.MSDRGCaseTypeFamilyID <> 0 OR OBJ.APRDRGCaseTypeFamilyID <> 0"); + break; + }; + break; + case "dss": + switch (table.TableName) + { + case "CaseTypeDRGMapping": + table.Init(new[] { "DRGID" }, keyColumns: new[] { "DRGID" }); + break; + case "CaseTypeEntity": + table.Init(new[] { "EntityID", "CaseTypeEntityID" }, + keyColumns: new[] { "EntityID", "CaseTypeEntityID" }); + break; + case "CaseTypeFamily": + table.Init(new[] { "Name", "CaseTypeFamilyGlobalID", "CaseTypeFamilyID" }, + keyColumns: new[] { "Name", "CaseTypeFamilyGlobalID" }); + break; + case "CaseTypeFamilyMappingAPRDRG": + table.Init(new[] { "APRDRGCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }, + keyColumns: new[] { "APRDRGCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }); + break; + case "CaseTypeFamilyMappingCPT": + table.Init(new[] { "CPTCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }, + keyColumns: new[] { "CPTCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }); + break; + case "CaseTypeFamilyMappingICD10": + table.Init(new[] { "ICD10Code", "MSDRGCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }, + keyColumns: new[] { "ICD10Code", "MSDRGCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID" }); + break; + case "CaseTypeFamilyVersion": + table.Init(new[] { "CaseTypeFamilyVersionID" }, + keyColumns: new[] { "CaseTypeFamilyVersionID" }); + break; + case "DimCaseType": + table.Init(new[] { "CaseTypeFamilyID", "CaseTypeId", "Name" }, jsonColumns: new[] { "CaseTypeConfigJSON" }); + break; + }; + break; + }; + }); + if (ShowTableNames) tables.Select(t => t.SchemaTable).Dump(nameof(ShowTableNames)); + if (ShowTableList) tables.Dump(nameof(ShowTableList)); + DoTheComparisons(connections, tables); +} + +// Define other methods and classes here + +#region Gather Table Information + +public string GetTableQuery() +{ + var tableSchemas = string.Join(", ", SchemasAndTablesToReview.Select(sattr => $"'{sattr.SchemaName}'")); + var tableList = string.Join("\r\n", SchemasAndTablesToReview.ConvertAll(sattr => + { + if (sattr.TableNames?.Any(cn => cn == "*") ?? true) + { + return $"\r\nWHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' THEN 1"; + } + else + { + var result = ""; + if (sattr.TableNames.Any(tn => tn.Contains("%"))) + { + result += sattr.TableNames.Where(tn => tn.Contains("%")) + .Aggregate("", (x, y) => $"{x}\r\nWHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' AND c.TABLE_NAME LIKE '{y}' THEN 1"); + } + if (sattr.TableNames.Any(tn => !tn.Contains("%"))) + { + result += $"\r\nWHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' AND c.TABLE_NAME IN ({string.Join(", ", sattr.TableNames.Where(tn => !tn.Contains("%")).Select(tn => $"'{tn}'"))}) THEN 1"; + } + return result; + } + })); + return $@"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ({tableSchemas}) +AND (CASE {tableList} +ELSE 0 +END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; +} + +public IList GetTables() +{ + var tableQuery = GetTableQuery(); + if (ShowTableQuery) tableQuery.Dump(nameof(ShowTableQuery)); + var tablesToRemove = SchemasAndTablesToReview.Where(sattr => sattr.ExcludeTables.Any()).SelectMany(sattr => sattr.ExcludeTables.Select(et => new { sattr.SchemaName, ExcludeTable = et })); + var tables = ExecuteQueryDynamic(tableQuery).ToList(); + if (tablesToRemove.Any()) + { + if (ShowTablesToRemove) + tablesToRemove.Dump(nameof(ShowTablesToRemove)); + tables.RemoveAll(x => tablesToRemove.Any(sattr => sattr.SchemaName == x.TABLE_SCHEMA && sattr.ExcludeTable == x.TABLE_NAME)); + } + return tables + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_NAME }, + (g, d) => new Table(g.TABLE_SCHEMA, g.TABLE_NAME, + d.Select(y => new Column(y.COLUMN_NAME, y.DATA_TYPE, y.IsPrimaryKey)).ToList())) + .ToList(); +} + +public class Table +{ + public string SchemaName { get; set; } + public string TableName { get; set; } + public IList Columns { get; set; } = new List(); + public IList OrderBy { get; set; } = new List(); + public IList Exclude { get; set; } = new List(); + public IList KeyColumn { get; set; } = new List(); + public IList Json { get; set; } = new List(); + public string Where { get; set; } = ""; + internal string SchemaTable => $"{SchemaName}.{TableName}"; + public string SqlSelect => $"select TOP({TopRows}) \r\n\t{SelectColumns}\r\nfrom {SchemaTable} OBJ{Where}{OrderByStatement}"; + internal string SelectColumns => !Columns?.Any() ?? true ? "*" : string.Join(",\r\n\t", Columns.Where(c => !Exclude.ToList().Contains(c.ColumnName)).Select(c => c.ColumnName)); + internal string OrderByStatement => !OrderBy?.Any() ?? true ? "" : "\r\nOrder By " + string.Join(", ", OrderBy.Select(ob => $"{ob.ColumnName}{(ob.IsDescending ? " DESC" : "")}")); + + public Table(string schemaName, string tableName) + { + SchemaName = schemaName; + TableName = tableName; + Columns = new List(); + OrderBy = new List(); + } + + public Table(string schemaName, string tableName, IEnumerable columns) + : this(schemaName, tableName) + { + Columns = columns.ToList(); + } + + public Table(string schemaName, string tableName, IEnumerable columns, IEnumerable orderBy) + : this(schemaName, tableName, columns) + { + OrderBy = orderBy.ToList(); + } + + /// + /// + /// + /// + /// Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + /// + public void Init(IEnumerable orderBys = null, IEnumerable excludes = null, IEnumerable keyColumns = null, IEnumerable jsonColumns = null, string where = "") + { + Init(orderBys?.Distinct().Select(o => new OrderBy(o.Split('|').Last(), o.StartsWith("D|", StringComparison.CurrentCultureIgnoreCase))) ?? null, + excludes?.Distinct(), keyColumns?.Distinct(), jsonColumns?.Distinct(), where); + } + + /// + /// + /// + /// + /// Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + /// + public void Init(IEnumerable orderBys = null, IEnumerable excludes = null, IEnumerable keyColumns = null, IEnumerable jsonColumns = null, string where = "") + { + if (orderBys != null) + OrderBys(orderBys.Where(x => Columns.Select(c => c.ColumnName).Contains(x.ColumnName))); + if (excludes != null) + Excludes(excludes.Where(x => Columns.Select(c => c.ColumnName).Contains(x))); + if (keyColumns != null) + KeyColumns(keyColumns.Where(x => Columns.Select(c => c.ColumnName).Contains(x))); + if (jsonColumns != null) + JsonColumns(jsonColumns.Where(x => Columns.Select(c => c.ColumnName).Contains(x))); + if (!string.IsNullOrEmpty(where)) + where = $"\r\nwhere {where}"; + } + + /// + /// Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + /// + public void OrderBys(IEnumerable orderBys) + { + OrderBy.Clear(); + ((List)OrderBy).AddRange(orderBys.Where(o => Columns.Select(c => c.ColumnName).Contains(o.ColumnName, StringComparer.CurrentCultureIgnoreCase))); + } + + public void Excludes(IEnumerable excludes) + { + Exclude.Clear(); + ((List)Exclude).AddRange(excludes.Where(e => Columns.Select(c => c.ColumnName).Contains(e, StringComparer.CurrentCultureIgnoreCase))); + } + + public void KeyColumns(IEnumerable keyColumns) + { + KeyColumn.Clear(); + ((List)KeyColumn).AddRange(keyColumns.Where(kc => Columns.Select(c => c.ColumnName).Contains(kc, StringComparer.CurrentCultureIgnoreCase))); + KeyColumn.Reverse().ToList().ForEach(kc => { + var col = Columns.Single(c => c.ColumnName == kc); + Columns.Remove(col); + Columns.Insert(0, col); + }); + } + + public void JsonColumns(IEnumerable jsonColumns) + { + Json.Clear(); + ((List)Json).AddRange(jsonColumns.Where(jc => Columns.Select(c => c.ColumnName).Contains(jc, StringComparer.CurrentCultureIgnoreCase))); + } +} + +public class Column +{ + public string ColumnName { get; set; } + public string DataType { get; set; } + public bool IsPrimaryKey { get; set; } + public Column(string columnName, string dataType = "", bool isPrimaryKey = false) + { + ColumnName = columnName; + DataType = dataType; + IsPrimaryKey = isPrimaryKey; + } +} + +public class OrderBy +{ + public string ColumnName { get; set; } + public bool IsDescending { get; set; } = false; + + public OrderBy(string columnName, bool isDescending = false) + { + ColumnName = columnName; + IsDescending = isDescending; + } + +} + +public class TablesAndColumns +{ + public string SchemaName { get; set; } + public IEnumerable TableNames { get; set; } + public IEnumerable ExcludeTables { get; set; } + public TablesAndColumns(string schemaName, IEnumerable tables = null, IEnumerable excludeTables = null) + { + SchemaName = schemaName; + TableNames = tables ?? new string[] { "*" }; + ExcludeTables = excludeTables ?? new string[] { }; + } +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public IEnumerable OrderBy { get; set; } + public OrderByInformation(string tableName, IEnumerable columns) + { + TableName = tableName; + OrderBy = columns + .Select(c => + new OrderBy(c.StartsWith("D|") ? c.Substring(2) : c, + c.StartsWith("D|"))); + } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public ColumnsToExclude(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +public class JsonColumns +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public JsonColumns(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +#endregion + +#region Do the comparisons + +public void DoTheComparisons(Connections connections, IEnumerable
tables) +{ + foreach (var table in tables) + { + var sql = table.SqlSelect; + var dataLegacy = GetData(connections.Legacy, sql, table.TableName).AsEnumerable().ToList(); + var dataUpdate = GetData(connections.Update, sql, table.TableName).AsEnumerable().ToList(); + + var compare = new List(); + var jsonColumns = table.Json.ToList() ?? null; + var keyColumns = table.KeyColumn.ToList() ?? null; + var idx = 0; + dataLegacy + .ForEach(legacyRow => + { + DataRow updateRow = default(DataRow); + if (table.KeyColumn.Any()) + { + var keys = string.Join("|", table.KeyColumn.Select(kc => $"{legacyRow.Field(kc)}")); + updateRow = dataUpdate + .FirstOrDefault(y => keys == string.Join("|", table.KeyColumn.Select(kc => $"{y.Field(kc)}"))); + } + else + { + if (dataUpdate.Count() > idx) + updateRow = dataUpdate[idx++]; + } + if ((ShowMissingUpdate && updateRow == null) || + (updateRow != null && JsonConvert.SerializeObject(legacyRow.ItemArray) != JsonConvert.SerializeObject(updateRow.ItemArray))) + compare.Add(new CompareSet(compare.Count, legacyRow, updateRow, jsonColumns, keyColumns)); + }); + if (ShowMissingLegacy && table.KeyColumn.Any()) + { + dataUpdate + .ForEach(updateRow => + { + DataRow legacyRow = default(DataRow); + if (table.KeyColumn.Any()) + { + var keys = string.Join("|", table.KeyColumn.Select(kc => $"{updateRow.Field(kc)}")); + legacyRow = dataLegacy + .FirstOrDefault(y => keys == string.Join("|", table.KeyColumn.Select(kc => $"{y.Field(kc)}"))); + } + if (legacyRow == null) + compare.Add(new CompareSet(compare.Count, legacyRow, updateRow, jsonColumns, keyColumns)); + }); + } + if (compare.Any()) + { + compare.OrderBy(c => c.OrderBy) + .Dump($"{table.SchemaTable} ( {compare.Count()} / {dataLegacy.Count} / {dataUpdate.Count} rows )", TableDumpDepth); + } + else + { + "No differences found in data".Dump($"{table.SchemaTable} ( 0 / {dataLegacy.Count} / {dataUpdate.Count} rows )"); + } + } +} + +public class Connections +{ + public ServerInstance Legacy { get; set; } + public ServerInstance Update { get; set; } +} + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + + public ServerInstance(string server, string database) + { + Server = server; + Database = database; + } +} + +public DataTable GetData(ServerInstance serverInstance, string sql, string tableName) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var datatable = new DataTable(); + var adapter = new SqlDataAdapter(sql, conn); + try + { + adapter.Fill(datatable); + } + catch (Exception) + { + sql.Dump(nameof(sql)); + throw; + } + datatable.TableName = tableName; + return datatable; + } +} + +public class CompareSet +{ + internal int Row { get; set; } + internal IList ColumnNames { get; set; } + internal IList Legacy { get; set; } + internal IList Update { get; set; } + internal int OrderBy { get; set; } = 0; + public IList Rows { get; set; } + internal IList JsonColumns { get; set; } + internal IList KeyColumns { get; set; } + public CompareSet(int row, DataRow right, DataRow left, IList jsonColumns, IList keyColumns) + { + Row = ++row; + if (right == null) + { + ColumnNames = left.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + } + else + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + } + Legacy = right?.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + OrderBy = (right != null ? 0 : 2) + (left != null ? 0 : 1); + JsonColumns = jsonColumns ?? new List(); + KeyColumns = keyColumns ?? new List(); + Rows = ColumnNames.Select((c, i) => new Row(row, c, Legacy?[i], Update?[i], JsonColumns?.Contains(c, StringComparer.CurrentCultureIgnoreCase) ?? false)).ToList(); + } + + public CompareSet(int row, DataRow right, DataRow left) + : this(row, right, left, null, null) + { + } + + object ToDump() => new + { + Row = $"{Row}", + Rows = Rows.Select(x => new + { + Column = (x.Left ?? "").Equals(x.Right ?? "") + ? KeyColumns.Contains((string)x.Column) + ? new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:cyan;color:black"), x.Column)) + : (object)x.Column + : new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:lightyellow;color:black"), x.Column)), + Legacy = x.Left, + Update = x.Right + }) + }; + +} + +public class Row +{ + public int RowId { get; set; } + public string Column; + public bool IsJson; + public object Left; + public object Right; + + public Row(int row, string column, object left, object right) + { + RowId = row; + Column = column; + Left = left; + Right = right; + } + + public Row(int row, string column, object left, object right, bool isJson) + : this(row, column, left, right) + { + + IsJson = isJson; + if (!isJson) return; + if (left != null) + { + Left = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(left.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + if (right != null) + { + Right = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(right.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + } + +} + +#endregion \ No newline at end of file diff --git a/DB Query with Lambda Expressions.linq b/DB Query with Lambda Expressions.linq new file mode 100644 index 0000000..4223411 --- /dev/null +++ b/DB Query with Lambda Expressions.linq @@ -0,0 +1,460 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + <RuntimeDirectory>\System.Linq.Expressions.dll + <RuntimeDirectory>\System.Linq.Queryable.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Linq.Dynamic + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private List SchemasAndTablesToReview = new List(); +private List OrderByStatements = new List(); +private List ColumnsToBeExcluded = new List(); +private List JsonColumnsToBeParsed = new List(); +private Dictionary JoinClauses = new Dictionary(); +private static Dictionary WhereClauses = new Dictionary(); +public static int TopRows = 1000;//int.MaxValue; + +void Main() +{ + SchemasAndTablesToReview.Clear(); + SchemasAndTablesToReview.Add(new TablesAndColumns("cci", new[] {"VariationOpportunity"})); + WhereClauses.Clear(); + WhereClauses.Add("clientdss.FactPatientEncounterSummary", "OBJ.MSDRGCaseTypeFamilyID <> 0 OR OBJ.APRDRGCaseTypeFamilyID <> 0"); + OrderByStatements.AddRange(new[] + { + new OrderByInformation("cci.InitiativeWorkflowHistory", new [] {"FromStep","ToStep"}), + new OrderByInformation("cci.VariationEncounterSavingInfo", new []{"EncounterRecordNumber","PhysicianID"}), + new OrderByInformation("cci.FactOpportunityMetric", new []{"FiscalYearID","FiscalMonthID"}), + new OrderByInformation("cci.FactOpportunitySavings", new []{"FiscalyYearID","FiscalMonthID"}), + new OrderByInformation("cci.Initiative", new []{"Name"}), + new OrderByInformation("cci.VariationOpportunity", new []{"CaseTypeEntityId", "CostDriver"}), + new OrderByInformation("clientdss.FactPatientEncounterSummary", new []{"EncounterRecordNumber"}), + new OrderByInformation("dss.CaseTypeFamily", new []{"Name", "CaseTypeFamilyGlobalID", "CaseTypeFamilyID"}), + new OrderByInformation("dss.CaseTypeFamilyMappingCPT", new []{"CPTCode", "CaseTypeFamilyVersionID", "CaseTypeFamilyID"}), + new OrderByInformation("dss.DimCaseType", new []{"CaseTypeFamilyID", "CaseTypeId", "Name"}) + }); + JoinClauses.Clear(); + JoinClauses.Add("cci.VariationOpportunity", "new(CaseTypeEntityId as firstKey, CostDriver as secondKey)"); + ColumnsToBeExcluded.AddRange(new[] + { + new ColumnsToExclude("cci.SystemSetting", new [] {"IsEncrypted"}), + new ColumnsToExclude("cci.Configuration", new [] {"InitiativeIsSimplifiedWorkflow"}), + new ColumnsToExclude("clientdss.FactPatientEncounterSummary", new [] {"MikeQAtest1ID", "CustomJesseValidatingAllOthers", "CustomNewCalculatedSystemFieldasdf"}) + }); + JsonColumnsToBeParsed.AddRange(new[] + { + new JsonColumns("dss.DimCaseType", new [] {"CaseTypeConfigJSON"}) + }); + + var tables = GetTables(); + var connections = new Connections { + Legacy = new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod 20190708.1"), + Update = new ServerInstance("D0001-SQL-11.sdt.local","jazz tst master prod") + }; + DoTheComparisons(connections, tables); +} + +// Define other methods and classes here + +#region Gather Table Information + +public string GetTableQuery() +{ + var tableSchemas = string.Join(", ", SchemasAndTablesToReview.Select(sattr => $"'{sattr.SchemaName}'")); + var tableList = string.Join("\r\n", SchemasAndTablesToReview.ConvertAll(sattr => + { + if (sattr.TableNames?.Any(cn => cn == "*") ?? true) + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' THEN 1"; + } + else + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' AND c.TABLE_NAME IN ({string.Join(", ", sattr.TableNames.Select(cn => $"'{cn}'"))}) THEN 1"; + } + })); + return $@"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ({tableSchemas}) +AND (CASE +{tableList} +ELSE 0 +END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; +} + +public IList
GetTables() +{ + var tableQuery = GetTableQuery(); + return ExecuteQueryDynamic(tableQuery) + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_NAME }, (g, d) => new Table + { + SchemaName = g.TABLE_SCHEMA, + TableName = g.TABLE_NAME, + Columns = d + .Select(y => new Column + { + ColumnName = y.COLUMN_NAME, + DataType = y.DATA_TYPE, + IsPrimaryKey = y.IsPrimaryKey + }), + OrderBy = OrderByStatements?.SingleOrDefault(obs => obs.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.OrderBy, + Exclude = ColumnsToBeExcluded?.SingleOrDefault(ctbe => ctbe.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.ColumnNames ?? new List(), + Json = JsonColumnsToBeParsed?.SingleOrDefault(ctbe => ctbe.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.ColumnNames ?? new List(), + Where = WhereClauses.ContainsKey($"{g.TABLE_SCHEMA}.{g.TABLE_NAME}") ? $"\r\nwhere {WhereClauses[$"{g.TABLE_SCHEMA}.{g.TABLE_NAME}"]}" : "" + }).ToList(); +} + +public class Table +{ + public string SchemaName { get; set; } + public string TableName { get; set; } + public IEnumerable Columns { get; set; } + public IEnumerable OrderBy { get; set; } + public IEnumerable Exclude { get; set; } + public IEnumerable Json { get; set; } + public string Where { get; set; } = ""; + internal string SchemaTable => $"{SchemaName}.{TableName}"; + public string SqlSelect => $"select TOP({TopRows}) \r\n\t{SelectColumns}\r\nfrom {SchemaTable} OBJ{Where}{OrderByStatement}"; + internal string SelectColumns => !Columns?.Any() ?? true ? "*" : string.Join(",\r\n\t", Columns.Where(c => !Exclude.ToList().Contains(c.ColumnName)).Select(c => c.ColumnName)); + internal string OrderByStatement => !OrderBy?.Any() ?? true ? "" : "\r\nOrder By " + string.Join(", ", OrderBy.Select(ob => $"{ob.ColumnName}{(ob.IsDescending ? " DESC" : "")}")); +} + +public class Column +{ + public string ColumnName { get; set; } + public string DataType { get; set; } + public bool IsPrimaryKey { get; set; } +} + +public class OrderBy +{ + public string ColumnName { get; set; } + public bool IsDescending { get; set; } = false; +} + +public class TablesAndColumns +{ + public string SchemaName { get; set; } + public IEnumerable TableNames { get; set; } + public TablesAndColumns(string schemaName, IEnumerable tables) + { + SchemaName = schemaName; + TableNames = tables; + } +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public IEnumerable OrderBy { get; set; } + public OrderByInformation(string tableName, IEnumerable columns) + { + TableName = tableName; + OrderBy = columns.Select(c => new OrderBy + { + ColumnName = c.StartsWith("D|") ? c.Substring(2) : c, + IsDescending = c.StartsWith("D|") + }); + } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public ColumnsToExclude(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +public class JsonColumns +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public JsonColumns(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +#endregion + +#region Do the comparisons + +public void DoTheComparisons(Connections connections, IEnumerable
tables) +{ + foreach (var table in tables) + { + var sql = table.SqlSelect; + var dataLegacy = GetData(connections.Legacy, sql, table.TableName); + var dataUpdate = GetData(connections.Update, sql, table.TableName); + + var legacy = dataLegacy.Rows; + var update = dataUpdate.Rows; + ParameterExpression pe1 = Expression.Parameter(dataLegacy.Columns["CaseTypeEntityId"].DataType, "CaseTypeEntityId"); + ParameterExpression pe2 = Expression.Parameter(dataLegacy.Columns["CostDriver"].DataType, "CostDriver"); + IQueryable legacyTable = dataLegacy.AsEnumerable().AsQueryable(); + IEnumerable updateTable = dataUpdate.AsEnumerable(); + var query = legacyTable.Join( + updateTable, + "new(get_Item(4) as CostDriver, get_Item(34) as CaseTypeEntityId)", + "new(get_Item(4) as CostDriver, get_Item(34) as CaseTypeEntityId)", + "new(outer as legacy, inner as update)" + ); + LambdaExpression le = System.Linq.Dynamic.DynamicExpression.ParseLambda(dataLegacy.AsEnumerable().AsQueryable().ElementType, + null, "new(CaseTypeEntityId as FirstKey, CostDriver as SecondKey)", "new( + // var test = update.AsQueryable().MyJoin(legacy.AsQueryable(), "new(CaseTypeEntityId as firstKey, CostDriver as secondKey)", +// "new(CaseTypeEntityId as firstKey, CostDriver as secondKey)", +// "new inner as legacy, outer as update)"); + var idxCount = legacy.Count; + var compare = new List(); + var jsonColumns = tables.SingleOrDefault(t => t.SchemaTable == table.TableName)?.Json.ToList(); + foreach (var row in Enumerable.Range(0, idxCount)) + { + var r = legacy[row]; + if (row < update.Count) + { + var u = update[row]; + var rJson = JsonConvert.SerializeObject(r.ItemArray); + var uJson = JsonConvert.SerializeObject(u.ItemArray); + if (rJson != uJson) + { + if (jsonColumns == null) + { + compare.Add(new CompareSet(r, u)); + } + else + { + compare.Add(new CompareSet(r, u, jsonColumns)); + } + } + } + else + { + if (jsonColumns == null) + { + compare.Add(new CompareSet(r, null)); + } + else + { + compare.Add(new CompareSet(r, null, jsonColumns)); + } + } + } + if (compare.Any()) + { + compare.Dump($"{table.TableName} ({compare.Count()}/{dataLegacy.Rows.Count} rows)", 2); + } + else + { + "No differences found in data".Dump($"{table.TableName} (0/{dataLegacy.Rows.Count} rows)"); + } + } +} + +/* +public static IQueryable MyJoin(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) +{ + if (inner == null) throw new ArgumentNullException("inner"); + if (outerSelector == null) throw new ArgumentNullException("outerSelector"); + if (innerSelector == null) throw new ArgumentNullException("innerSelector"); + if (resultsSelector == null) throw new ArgumentNullException("resultsSelctor"); + + LambdaExpression outerSelectorLambda = DynamicExpression.ParseLambda(outer.ElementType, null, outerSelector, values); + LambdaExpression innerSelectorLambda = DynamicExpression.ParseLambda(inner.AsQueryable().ElementType, null, innerSelector, values); + + ParameterExpression[] parameters = new ParameterExpression[] { + Expression.Parameter(outer.ElementType, "outer"), Expression.Parameter(inner.AsQueryable().ElementType, "inner") }; + LambdaExpression resultsSelectorLambda = DynamicExpression.ParseLambda(parameters, null, resultsSelector, values); + + return outer.Provider.CreateQuery( + Expression.Call( + typeof(Queryable), "Join", + new Type[] { outer.ElementType, inner.AsQueryable().ElementType, outerSelectorLambda.Body.Type, resultsSelectorLambda.Body.Type }, + outer.Expression, inner.AsQueryable().Expression, Expression.Quote(outerSelectorLambda), Expression.Quote(innerSelectorLambda), Expression.Quote(resultsSelectorLambda))); +} + +public static IQueryable Join(this IQueryable outer, IEnumerable inner, string outerSelector, string innerSelector, string resultsSelector, params object[] values) +{ + return (IQueryable)Join((IQueryable)outer, (IEnumerable)inner, outerSelector, innerSelector, resultsSelector, values); +} +*/ +public class Connections +{ + public ServerInstance Legacy { get; set; } + public ServerInstance Update { get; set; } +} + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + + public ServerInstance(string server, string database) + { + Server = server; + Database = database; + } +} + +public DataTable GetData(ServerInstance serverInstance, string sql, string tableName) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var datatable = new DataTable(); + var adapter = new SqlDataAdapter(sql, conn); + try + { + adapter.Fill(datatable); + } + catch (Exception ex) + { + sql.Dump(nameof(sql)); + throw; + } + datatable.TableName = tableName; + return datatable; + } +} + +public class CompareSet +{ + internal IList ColumnNames { get; set; } + internal IList Legacy { get; set; } + internal IList Update { get; set; } + public IList Rows { get; set; } + internal IList JsonColumns { get; set; } + public CompareSet(DataRow right, DataRow left) + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + Legacy = right.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + Rows = ColumnNames.Select((c, i) => new Row(c, Legacy[i], Update?[i])).ToList(); + } + public CompareSet(DataRow right, DataRow left, IList jsonColumns) + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + Legacy = right.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + JsonColumns = jsonColumns; + Rows = ColumnNames.Select((c, i) => new Row(c, Legacy[i], Update?[i], JsonColumns.Contains(c, StringComparer.CurrentCultureIgnoreCase))).ToList(); + } + +} + +public class Row +{ + public string Column; + public bool IsJson; + public object Left; + public object Right; + + public Row(string column, object left, object right) + { + Column = column; + Left = left; + Right = right; + } + + public Row(string column, object left, object right, bool isJson) + : this(column, left, right) + { + IsJson = isJson; + if (!isJson) return; + Left = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(left.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + if (right == null) return; + Right = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(right.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + + object ToDump() => new + { + Column = Left.Equals(Right ?? "") ? (object)Column : new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:lightyellow;color:black"), Column)), + Legacy = Left, + Update = Right + }; +} + +#endregion \ No newline at end of file diff --git a/DDEN SQL Server List.linq b/DDEN SQL Server List.linq new file mode 100644 index 0000000..84e9281 --- /dev/null +++ b/DDEN SQL Server List.linq @@ -0,0 +1,66 @@ + + + 877f607f-de79-449a-a047-e6d0c5b9e5d2 + true + DDEN-SQL-SMC-01.sdt.local + smc dev + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var dbInformation = (from dbInfo in ViewDatabaseInfo +where dbInfo.IsProduction.HasValue && dbInfo.IsProduction.Value +orderby dbInfo.Description, dbInfo.DatabaseName +select dbInfo); +dbInformation +.Dump(); \ No newline at end of file diff --git a/Dashboard extrapolation.linq b/Dashboard extrapolation.linq new file mode 100644 index 0000000..a477bda --- /dev/null +++ b/Dashboard extrapolation.linq @@ -0,0 +1,148 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.Dynamic + + +var emptyGuid = Guid.Empty.ToString(); +var dashboards = (from dashboard in DesktopTemplates + join module in SystemCenterModules on dashboard.ModuleGUID equals module.ModuleGUID + join solution in SystemCenterSolutions on module.SolutionGUID equals solution.SolutionGUID + where dashboard.IsLegacy == false && solution.IsStatusDisabled == false + select new + { + solution = solution.Name, + primarySort = solution.SortOrder, + module = module.Name, + categories = module.SystemCenterCategories + .Where(c => c.IsMaintenanceMode == true).OrderBy(c => c.SortOrder) + .Select(c => new { c.Name, SortOrder = c.SortOrder.ToString() }).ToList(), + secondarySort = module.SortOrder, + dashboard.DesktopTemplateGUID, + dashboard.Name, + dashboard.Description, + parameters = dashboard.DesktopParameters.Any() + ? dashboard.DesktopParameters.Select(p => new + { + p.Name, + p.ColumnName, + p.DimensionName, + p.AttributeName, + p.DataSourceGUID, + ExcludedWidgetGuids = string.IsNullOrEmpty(p.ExcludedWidgetGuidsCSV) ? null : p.ExcludedWidgetGuidsCSV.Split(',') + }).Distinct().ToList() + : null, + // columns = dashboard.DesktopColumns.Any() ? dashboard.DesktopColumns.ToList() : null, + widgets = dashboard.DashboardWidgets.Any() + ? dashboard.DashboardWidgets.Select(w => new + { + w.Name, + w.Row, + w.Col, + w.Height, + w.Width, + w.WidgetClassName, + DataSourceGUID = w.DataSourceGUID.ToString() == "00000000-0000-0000-0000-000000000000" ? "" : w.DataSourceGUID.ToString(), + WidgetJSON = (JsonConvert.DeserializeObject(w.WidgetJSON) as IDictionary) + }) + .Select(w => new + { + w.Name, + w.Row, + w.Col, + w.Height, + w.Width, + w.WidgetClassName, + w.DataSourceGUID, + w.WidgetJSON, + ReportGuid = w.WidgetClassName == "Grid" || w.WidgetClassName == "Chart" || + (w.WidgetClassName == "Metric" && w.WidgetJSON["ReportGuid"] != emptyGuid) + ? w.WidgetJSON["ReportGuid"] + : null + }) + .OrderBy(w => w.Row).ThenBy(w => w.Col).ToList() + : null, + desktop = dashboard.DesktopWidgets.Any() + ? dashboard.DesktopWidgets.Select(w => new + { + w.Name, + w.Height, + w.DesktopTemplateGUID, + w.WidgetFullName, + w.WidgetXML + }).ToList() + : null + }) +.OrderBy(x => x.primarySort).ThenBy(x => x.secondarySort).ThenBy(x => x.Name).ToList(); +dashboards.Dump(); +dashboards.Where(d => d.parameters != null).SelectMany(d => d.parameters) +.OrderBy(d => d.DimensionName).ThenBy(d => d.AttributeName).Dump(); +dashboards.SelectMany(d => d.widgets.Where(w => w.WidgetClassName == "Report" || w.WidgetClassName == "Chart") + .Select(w => new {Dashboard = d.Name, Report = w.Name, w.Row, w.Col, w.Height, w.Width, w.WidgetClassName, w.DataSourceGUID, w.ReportGuid})) +.OrderBy(d => d.Dashboard).ThenBy(d => d.Report).Dump(); +dashboards.SelectMany(d => d.widgets.Where(w => w.WidgetClassName == "Metric") + .Select(w => new { Dashboard = d.Name, Report = w.Name, w.Row, w.Col, w.Height, w.Width, w.WidgetClassName, w.DataSourceGUID, w.WidgetJSON })) +.OrderBy(d => d.Dashboard).ThenBy(d => d.Report).Dump(); \ No newline at end of file diff --git a/DateTime Differences.linq b/DateTime Differences.linq new file mode 100644 index 0000000..ae0b8d4 --- /dev/null +++ b/DateTime Differences.linq @@ -0,0 +1,84 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + TimePeriodLibrary.NET + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Itenso.TimePeriod + + +var date1 = DateTime.Now.AddMonths(-6); +date1.Dump(); + +var date2 = DateTime.Now.AddMonths(-19).AddDays(-14).AddHours(-25); +date2.Dump(); +"".PadLeft(40, '=').Dump(); +var tock = date1.Subtract(date2).Ticks; + +TimeSpan ts = date1 - date2; +$"{ts.TotalDays} Days".Dump(); +"".PadLeft(40, '-').Dump(); + +var dateDiff = new DateDiff(date2, date1); +$"{dateDiff.ElapsedYears} Years {dateDiff.ElapsedMonths} Months {dateDiff.ElapsedDays} Days".Dump(); + +"".PadLeft(40, '-').Dump(); +var xx = new DateTime(Math.Abs(tock)); +xx.Dump(); +xx.Year.Dump(); +xx.Month.Dump(); +xx.Day.Dump(); \ No newline at end of file diff --git a/DateTime Extensions Tester.linq b/DateTime Extensions Tester.linq new file mode 100644 index 0000000..aa8397f --- /dev/null +++ b/DateTime Extensions Tester.linq @@ -0,0 +1,99 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + AWSSDK.Glue + AWSSDK.S3 + FluentAssertions + Newtonsoft.Json + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + FluentAssertions + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + for (var x = 0; x > -5; x--) + { + try + { + var testDate = DateTime.Now.AddYears(x); + testDate.Dump($"{x}"); + RunValidation(testDate); + } + catch (Exception ex) + { + $"{x} - {ex.Message}".Dump(); + } + } +} + +public void RunValidation(DateTime testDate) +{ + testDate.AddMilliseconds(-1).GetPrettyDate().Should().Be("just now"); + testDate.AddSeconds(-1).GetPrettyDate().Should().Be("just now"); + testDate.AddMinutes(-1).GetPrettyDate().Should().Be("1 minute ago"); + for (var x = -2; x >= -59; x--) + { + testDate.AddMinutes(-x).GetPrettyDate().Should().Be($"{x} minutes ago"); + } + testDate.AddHours(-1).GetPrettyDate().Should().Be("1 hour ago"); + for (var x = -2; x >= -23; x--) + { + testDate.AddHours(-x).GetPrettyDate().Should().Be($"{x} hours ago"); + } + testDate.AddDays(-1).GetPrettyDate().Should().Be("yesterday"); + for (var x = -2; x >= -364; x--) + { + testDate.AddDays(-x).GetPrettyDate().Should().Be($"{x} days ago"); + } + testDate.AddMonths(-1).GetPrettyDate().Should().Be("5 weeks ago"); + for (var x = -2; x >= -364; x--) + { + testDate.AddMonths(-x).GetPrettyDate().Should().Be($"{x} months ago"); + } +} + +// Define other methods and classes here diff --git a/DepartmentPatientCensus Analysis.linq b/DepartmentPatientCensus Analysis.linq new file mode 100644 index 0000000..40427e3 --- /dev/null +++ b/DepartmentPatientCensus Analysis.linq @@ -0,0 +1,95 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst CNE 20191210.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var configurationGuid = Guid.Parse("880C4912-5A58-40B7-ADB1-1F9BD365E6AF"); + var configuration = (from c in Configurations where c.ConfigurationGUID == configurationGuid select c).Single(); + //configuration.Dump(nameof(configuration)); + var baselineEndDate = configuration.WasteEndDate; + var baselineStartDate = baselineEndDate.AddYears(-1).AddDays(1); + (from dpc in DepartmentPatientCensus + where dpc.EnterTime < baselineEndDate && dpc.ExitTime > baselineStartDate + select new { dpc.RowID, dpc.DepartmentID, dpc.EncounterRecordNumber, dpc.EnterTime, dpc.ExitTime, dpc.IsNewborn, baselineStartDate, baselineEndDate }) + .ToList() + .GroupBy(ed => new { ed.DepartmentID, ed.EnterTime.Year, ed.EnterTime.Month, ed.EnterTime.Day, ed.EnterTime.Hour }, (g, d) => d.Select(x => new + { + g.DepartmentID, + g.Year, + g.Month, + g.Day, + g.Hour, + newbornEncounters = d.Where(y => y.IsNewborn).Count(), + encounters = d.Where(y => !y.IsNewborn).Count() + }).First()) + .Where(ed => new[] { 21398, 21915 }.Contains(ed.DepartmentID)) + .GroupBy(ed => ed.DepartmentID, (g, d) => new + { + DepartmentId = g, + Data = d.OrderBy(ed => ed.Year) + .ThenBy(ed => ed.Month) + .ThenBy(ed => ed.Day) + .ThenBy(ed => ed.Hour) + }) + .Dump(); +} + +// Define other methods and classes here diff --git a/Dev Page Logs.linq b/Dev Page Logs.linq new file mode 100644 index 0000000..b944285 --- /dev/null +++ b/Dev Page Logs.linq @@ -0,0 +1,71 @@ + + + a0281727-8f99-469c-a1e8-bda14dcbf030 + true + DDEN-SQL-LOG-01.sdt.local + jazz log dev + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +PageLogs.OrderByDescending(p => p.RowId) +.Where(p => p.UserName.Contains("tlamb")) +//.Between(p => p.RowId, 4826093, 4826100) +.Take(100).Dump(); +//Mapping.GetTables().Where(t => t.TableName == "[PageLog]") +//.First().RowType.DataMembers +//.Where(dm => dm.DbType != null) +//.Select( dm => new {dm.Name, dm.DbType, dm.Type, dm.MappedName, dm.IsPrimaryKey}) +//.Dump(); +// \ No newline at end of file diff --git a/DimCaseType QA Master.linq b/DimCaseType QA Master.linq new file mode 100644 index 0000000..68e6aca --- /dev/null +++ b/DimCaseType QA Master.linq @@ -0,0 +1,92 @@ + + LinqToCsv + LINQtoCSV + Newtonsoft.Json + + +void Main() +{ + var thefile = @"D:\Users\tlamb\Downloads\DimCaseType QA Master.csv"; + var csvdata = File.ReadAllLines(thefile); + //csvdata.Dump(); + var inputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', + FirstLineHasColumnNames = false, + EnforceCsvColumnAttribute = true, + IgnoreUnknownColumns = true, + UseFieldIndexForReadingData = true + }; + var cc = new CsvContext(); + var data = cc.Read(thefile, inputFileDescription).ToList(); + //data.Dump(); + string.Join("\r\n", + data.ConvertAll(d => $"UPDATE dss.DimCaseType SET CaseTypeConfigJSON = '{d.CaseTypeConfigJSON}' WHERE Name = '{d.Name}' and CaseTypeID = {d.CaseTypeID};")).Dump(); +} + +// Define other methods and classes here +public class DimCaseType +{ + [CsvColumn(FieldIndex = 1)] + public int CaseTypeID { get; set; } + [CsvColumn(FieldIndex = 2)] + public string Name { get; set; } + [CsvColumn(FieldIndex = 3)] + public string CaseTypeConfigJSON { get; set; } + //public MSDRGCaseTypeConfiguration CaseTypeConfig => JsonConvert.DeserializeObject(CaseTypeConfigJSON); +} + +public class CaseTypeConfiguration +{ + public int PhysicianMinVolume { get; set; } = 0; +} + +public class DRGCaseTypeConfiguration : CaseTypeConfiguration +{ + public List AgeCohortIDInclusions { get; set; } = new List(); + public List PhysicianIDExclusions { get; set; } = new List(); + public StandardDeviationExclusions StandardDeviationExcludedTypeEnum { get; set; } = StandardDeviationExclusions.None; + public int LengthOfStayThreshold { get; set; } = 0; + public HashSet CPTCodes { get; set; } = new HashSet(); + public List PatientTypeRollupIDInclusions { get; set; } = new List(); +} + +public class MSDRGCaseTypeConfiguration : DRGCaseTypeConfiguration +#pragma warning restore S101 // Types should be named in PascalCase +{ + public HashSet CCMCCCategories { get; set; } = new HashSet(); + +} + +public enum CCMCCCategoryTypes +#pragma warning restore S2342 // Enumeration types should comply with a naming convention +{ + None, + CC, + MCC, + WO, + NA, + CCMCC +} + +public enum StandardDeviationExclusions +{ + None = 0, + TwoStdDev = 1, + ThreeStdDev = 2, + CustomLOSOutlier = 3 +} + +public enum PhysicianGroupingTypes +{ + Physician = 0, + Specialty = 1, + GroupAffiliation = 2 +} + +public enum CaseTypeCategories +{ + MSDRG = 0, + APRDRG = 1, + PatientPopulation = 2 +} diff --git a/Dynamic JSON object.linq b/Dynamic JSON object.linq new file mode 100644 index 0000000..5900e24 --- /dev/null +++ b/Dynamic JSON object.linq @@ -0,0 +1,9 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + + +var jsonStr = "[{\"HierarchyPath\":\"DEPT|DEPT|1|1|27|2|162\",\"Name\":\"10 - 2530 - NSMC IU NICU\"},{\"HierarchyPath\":\"DEPT|DEPT|1|1|27|2|266\",\"Name\":\"10 - 4000 - SL OPERATING ROOM\"}]"; +dynamic obj = JsonConvert.DeserializeObject(jsonStr); +string test = obj[0].HierarchyPath; +test.Dump(); \ No newline at end of file diff --git a/Encounter Performance Engine test.linq b/Encounter Performance Engine test.linq new file mode 100644 index 0000000..025353c --- /dev/null +++ b/Encounter Performance Engine test.linq @@ -0,0 +1,155 @@ + + + 580b3b8d-cc02-4a68-8fbd-d1ec374a25f2 + true + D0001-sql-11.sdt.local + jazz dev master Prod + true + + Newtonsoft.Json + Newtonsoft.Json.Linq + + +void Main() +{ + var oppGuid = Guid.Parse("ebe53c65-af17-4372-b7c1-18a6011f7d23"); + var opp = from eo in EncounterOpportunities + where eo.OpportunityGUID == oppGuid + select eo; + + var pti = from eopti in EncounterOpportunityPerformanceTrackingItems + where eopti.OpportunityGUID == oppGuid + orderby eopti.LevelID, eopti.Type + select new { performanceTrackingItem = JsonConvert.DeserializeObject(eopti.PerformanceTrackingItem) }; + + var metrics = from eopemd in EncounterOpportunityPerformanceEngineMetricData + where eopemd.OpportunityGUID == oppGuid + orderby eopemd.LevelID, eopemd.IsBaseline, eopemd.Type + select new + { + eopemd.LevelID, + eopemd.Type, + eopemd.IsBaseline, + months = new[] { + new {Name = "Month01", Value = eopemd.Month01}, + new {Name = "Month02", Value = eopemd.Month02}, + new {Name = "Month03", Value = eopemd.Month03}, + new {Name = "Month04", Value = eopemd.Month04}, + new {Name = "Month05", Value = eopemd.Month05}, + new {Name = "Month06", Value = eopemd.Month06}, + new {Name = "Month07", Value = eopemd.Month07}, + new {Name = "Month09", Value = eopemd.Month08}, + new {Name = "Month09", Value = eopemd.Month09}, + new {Name = "Month10", Value = eopemd.Month10}, + new {Name = "Month11", Value = eopemd.Month11}, + new {Name = "Month12", Value = eopemd.Month12} + } + }; + + //var jsonPti = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(pti[1]), Newtonsoft.Json.Formatting.Indented); + //jsonPti.Dump(); + opp.Dump(nameof(EncounterOpportunities)); + metrics.Dump(nameof(EncounterOpportunityPerformanceEngineMetricData)); + pti.FirstOrDefault().Dump(nameof(EncounterOpportunityPerformanceTrackingItems)); +} + +// Define other methods and classes here + +public class PerformanceMonthlyUnitData +{ + public int MonthID { get; set; } + public double RampUp { get; set; } + public double Units { get; set; } + public double UnitsYTD { get; set; } + public double Stats { get; set; } + public double StatsYTD { get; set; } + + /// + /// Units DivideBy Stats + /// + public double UnitsPerStat { get; set; } + public double UnitsPerStatYTD { get; set; } +} + +public class PerformanceMonthlySavingsData : PerformanceMonthlyUnitData +{ + public double Savings { get; set; } + public double SavingsYTD { get; set; } +} + +public class YearMonth +{ + public int FiscalYear { get; set; } + public int CalendarYear { get; set; } + + public DateTime FiscalYearMonth { get; set; } + public DateTime CalendarYearMonth { get; set; } + + public int FiscalYearID; + public int FiscalMonthID; +} + +public class TrackingYearMonth : YearMonth +{ + public bool IsAfterEffectiveDate { get; set; } + public bool IsBeforeTrackingDate { get; set; } + public bool IsCurrentMonth { get; set; } + public bool IsTrackedMonth { get; set; } +} + +public interface IPerformanceTrackingMonth +{ + TrackingYearMonth Month { get; set; } + double RampUp { get; set; } + double GoalUnits { get; set; } + double GoalUnitsYTD { get; set; } + double CommittedUnits { get; } + double CommittedUnitsYTD { get; set; } + double GoalUnitsOverall { get; set; } + double BaselineUnitsOverall { get; set; } + double BaselineStatsOverall { get; set; } + double TrackingUnitsOverall { get; set; } + double TrackingStatsOverall { get; set; } + PerformanceMonthlyUnitData BaselineMonthlyUnitData { get; set; } + PerformanceMonthlyUnitData TrackingMonthlyUnitData { get; set; } + PerformanceMonthlySavingsData GoalSavings { get; set; } + PerformanceMonthlySavingsData CommittedSavings { get; set; } + PerformanceMonthlySavingsData ActualSavings { get; set; } + double GoalUnitVariance { get; } + double ActualUnitVariance { get; } + double CommittedUnitVariance { get; } + double CommittedRate { get; } +} + +public class PerformanceTrackingMonth : IPerformanceTrackingMonth +{ + public TrackingYearMonth Month { get; set; } + public PerformanceMonthlyUnitData BaselineMonthlyUnitData { get; set; } + public PerformanceMonthlyUnitData TrackingMonthlyUnitData { get; set; } + public PerformanceMonthlySavingsData GoalSavings { get; set; } + public PerformanceMonthlySavingsData CommittedSavings { get; set; } + public PerformanceMonthlySavingsData ActualSavings { get; set; } + public double RampUp { get; set; } + public double BaselineUnitsOverall { get; set; } + public double BaselineStatsOverall { get; set; } + public double TrackingUnitsOverall { get; set; } + public double TrackingStatsOverall { get; set; } + public double GoalUnits { get; set; } + public double GoalUnitsYTD { get; set; } + public double GoalUnitsOverall { get; set; } + public double GoalUnitVariance { get; set; } + public double ActualUnitVariance { get; set; } + public double CommittedStats { get; set; } + public double CommittedUnits { get; set; } + public double CommittedUnitsYTD { get; set; } + public double CommittedUnitVariance { get; set; } + public double CommittedRate { get; set; } +} + +public class PerformanceTrackingItem +{ + public int GroupID { get; set; } + public string GroupName { get; set; } + + public IEnumerable MonthlyTrackingData { get; set; } +} \ No newline at end of file diff --git a/Evaluate QVI Bubble Chart.linq b/Evaluate QVI Bubble Chart.linq new file mode 100644 index 0000000..d842620 --- /dev/null +++ b/Evaluate QVI Bubble Chart.linq @@ -0,0 +1,55 @@ + + + bd4e97c5-84e7-4c61-80ca-8d53d7876af2 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + + +var config = (from c in Configurations where c.FiscalYearID == 2020 select c).First(); +var opps = (from OBJ in QVILineItemOpportunities + join qve in QualityVariationEvents on OBJ.QualityVariationEventID equals qve.QualityVariationEventID + where OBJ.ConfigurationGUID == config.ConfigurationGUID + && !OBJ.IsHidden + select new + { + OBJ.OpportunityGUID, + OBJ.InitiativeGUID, + OBJ.Savings, + // OBJ.DateModified, + // OBJ.DateCreated, + // OBJ.ConfigurationGUID, + // OBJ.IsHidden, + OBJ.TotalCasesWithQVI, + OBJ.TotalPatientDaysWithQVI, + OBJ.TotalCostWithQVI, + OBJ.NetRevenueWithQVI, + OBJ.BreakdownName, + OBJ.BreakdownID, + OBJ.CommittedSavingsLevel, + OBJ.TotalCases, + OBJ.Note, + OBJ.QualityVariationEventID, + QualityVariationEventName = qve.Name, + QualityVariationEventCategory = qve.Category, + qve.QVILineItemID, + QVILineItemName = qve.Name, + QVIName = qve.Category, + qve.SortOrder, + qve.ClinicalIndicatorID + }).ToList(); +opps +.GroupBy(p => p.QualityVariationEventCategory, +(category, qvi) => new +{ + Name = category, + Savings = qvi.Sum(x => x.Savings), + Cases = qvi.Sum(x => x.TotalCasesWithQVI), + SavingsMaxPotential = qvi.WeightedAverage(x => x.Savings.DivideBy(x.TotalCasesWithQVI), w => w.TotalCasesWithQVI), + QVISubItems = qvi.ToList() +}) +.OrderByDescending(p => p.Cases) +.ThenByDescending(p => p.Savings) +.Dump(); \ No newline at end of file diff --git a/FPES Encounter Summary analysis.linq b/FPES Encounter Summary analysis.linq new file mode 100644 index 0000000..8a1fdde --- /dev/null +++ b/FPES Encounter Summary analysis.linq @@ -0,0 +1,34 @@ + + + bd4e97c5-84e7-4c61-80ca-8d53d7876af2 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + + +var startDate = new DateTime(2019, 1, 1); +var endDate = new DateTime(2020, 1, 1); +var months = Enumerable.Range(1, 12).Select(i => new { month = i }).ToList(); +var data = (from fpes in FactPatientEncounterSummaries + join ctf in CaseTypeFamilies on fpes.MSDRGCaseTypeFamilyID equals ctf.CaseTypeFamilyID + where fpes.DischargeDateTime >= startDate && fpes.DischargeDateTime < endDate + && fpes.MSDRGCaseTypeFamilyID != 0 + group fpes by new { DischargeMonth = fpes.DischargeDateTime.Month, ctf.CaseTypeFamilyID, ctf.Name } into gpes + orderby gpes.Key.CaseTypeFamilyID, gpes.Key.DischargeMonth + select new + { + LevelID = 0, + Month = gpes.Key.DischargeMonth, + gpes.Key.CaseTypeFamilyID, + gpes.Key.Name, + Volume = gpes.Select(g => g.EncounterID).Distinct().Count(), + Revenue = gpes.Sum(g => g.NetRevenue), + TotalCost = gpes.Sum(g => g.TotalCosts) + }).ToList(); +var pes = months.GroupJoin(data, m => m.month, d => d.Month, (m, d) => d.DefaultIfEmpty()).SelectMany(m => m) +.OrderBy(m => m.CaseTypeFamilyID) +.ThenBy(m => m.Month); + +pes.Dump(); \ No newline at end of file diff --git a/FactPatientEncounterSummary Query Exceptions.linq b/FactPatientEncounterSummary Query Exceptions.linq new file mode 100644 index 0000000..c16bf4b --- /dev/null +++ b/FactPatientEncounterSummary Query Exceptions.linq @@ -0,0 +1,411 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.ComponentModel + + +private List SchemasAndTablesToReview = new List(); +private List OrderByStatements = new List(); +private List ColumnsToBeExcluded = new List(); +private List JsonColumnsToBeParsed = new List(); +private static Dictionary WhereClauses = new Dictionary(); +public static int TopRows = int.MaxValue; + +void Main() +{ + SchemasAndTablesToReview.AddRange(new[] + { + new TablesAndColumns("clientdss", new [] { "FactPatientEncounterSummary" }) + }); + WhereClauses.Add("clientdss.FactPatientEncounterSummary", "OBJ.MSDRGCaseTypeFamilyID <> 0 OR OBJ.APRDRGCaseTypeFamilyID <> 0"); + OrderByStatements.AddRange(new[] + { + new OrderByInformation("cci.InitiativeWorkflowHistory", new [] {"FromStep","ToStep"}), + new OrderByInformation("cci.VariationEncounterSavingInfo", new []{"EncounterRecordNumber","PhysicianID"}), + new OrderByInformation("cci.FactOpportunityMetric", new []{"FiscalYearID","FiscalMonthID"}), + new OrderByInformation("cci.FactOpportunitySavings", new []{"FiscalyYearID","FiscalMonthID"}), + new OrderByInformation("clientdss.FactPatientEncounterSummary", new []{"EncounterRecordNumber"}), + new OrderByInformation("dss.DimCaseType", new []{"CaseTypeFamilyID", "CaseTypeId", "Name"}) + }); + ColumnsToBeExcluded.AddRange(new[] + { + new ColumnsToExclude("cci.SystemSetting", new [] {"IsEncrypted"}), + new ColumnsToExclude("cci.Configuration", new [] {"InitiativeIsSimplifiedWorkflow"}), + new ColumnsToExclude("clientdss.FactPatientEncounterSummary", new [] {"MikeQAtest1ID", "CustomJesseValidatingAllOthers", "CustomNewCalculatedSystemFieldasdf"}) + }); + JsonColumnsToBeParsed.AddRange(new[] + { + new JsonColumns("dss.DimCaseType", new [] {"CaseTypeConfigJSON"}) + }); + + var tables = GetTables(); + var tableList = tables.Select(r => r.SchemaTable); + var connections = new ServerInstance[] { + new ServerInstance("D0011-SQL-01.sdt.local","jazz tst Southern Illinois 20190918.1", tableList), + new ServerInstance("D0011-SQL-01.sdt.local", "jazz tst Southern Illinois 20200331.1", tableList) + }.ToList(); + DoTheComparisons(connections, tables); +} + +// Define other methods and classes here + +#region Gather Table Information + +public string GetTableQuery() +{ + var tableSchemas = string.Join(", ", SchemasAndTablesToReview.Select(sattr => $"'{sattr.SchemaName}'")); + var tableList = string.Join("\r\n", SchemasAndTablesToReview.ConvertAll(sattr => + { + if (sattr.TableNames?.Any(cn => cn == "*") ?? true) + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' THEN 1"; + } + else + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' AND c.TABLE_NAME IN ({string.Join(", ", sattr.TableNames.Select(cn => $"'{cn}'"))}) THEN 1"; + } + })); + return $@"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ({tableSchemas}) +AND (CASE +{tableList} +ELSE 0 +END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; +} + +public IList
GetTables() +{ + var tableQuery = GetTableQuery(); + return ExecuteQueryDynamic(tableQuery) + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_NAME }, (g, d) => new Table + { + SchemaName = g.TABLE_SCHEMA, + TableName = g.TABLE_NAME, + Columns = d + .Select(y => new Column + { + ColumnName = y.COLUMN_NAME, + DataType = y.DATA_TYPE, + IsPrimaryKey = y.IsPrimaryKey + }), + OrderBy = OrderByStatements?.SingleOrDefault(obs => obs.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.OrderBy, + Exclude = ColumnsToBeExcluded?.SingleOrDefault(ctbe => ctbe.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.ColumnNames ?? new List(), + Json = JsonColumnsToBeParsed?.SingleOrDefault(ctbe => ctbe.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.ColumnNames ?? new List(), + Where = WhereClauses.ContainsKey($"{g.TABLE_SCHEMA}.{g.TABLE_NAME}") ? $"\r\nwhere {WhereClauses[$"{g.TABLE_SCHEMA}.{g.TABLE_NAME}"]}" : "" + }).ToList(); +} + +public class Table +{ + public string SchemaName { get; set; } + public string TableName { get; set; } + public IEnumerable Columns { get; set; } + public IEnumerable OrderBy { get; set; } + public IEnumerable Exclude { get; set; } + public IEnumerable Json { get; set; } + public string Where { get; set; } = ""; + internal string SchemaTable => $"{SchemaName}.{TableName}"; + public string SqlSelect => $"select TOP({TopRows}) \r\n\t{SelectColumns}\r\nfrom {SchemaTable} OBJ{Where}{OrderByStatement}"; + internal string SelectColumns => !Columns?.Any() ?? true ? "*" : string.Join(",\r\n\t", Columns.Where(c => !Exclude.ToList().Contains(c.ColumnName)).Select(c => c.ColumnName)); + internal string OrderByStatement => !OrderBy?.Any() ?? true ? "" : "\r\nOrder By " + string.Join(", ", OrderBy.Select(ob => $"{ob.ColumnName}{(ob.IsDescending ? " DESC" : "")}")); +} + +public class Column +{ + public string ColumnName { get; set; } + public string DataType { get; set; } + public bool IsPrimaryKey { get; set; } +} + +public class OrderBy +{ + public string ColumnName { get; set; } + public bool IsDescending { get; set; } = false; +} + +public class TablesAndColumns +{ + public string SchemaName { get; set; } + public IEnumerable TableNames { get; set; } + public TablesAndColumns(string schemaName, IEnumerable tables) + { + SchemaName = schemaName; + TableNames = tables; + } +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public IEnumerable OrderBy { get; set; } + public OrderByInformation(string tableName, IEnumerable columns) + { + TableName = tableName; + OrderBy = columns.Select(c => new OrderBy + { + ColumnName = c.StartsWith("D|") ? c.Substring(2) : c, + IsDescending = c.StartsWith("D|") + }); + } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public ColumnsToExclude(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +public class JsonColumns +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public JsonColumns(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +#endregion + +#region Do the comparisons + +public void DoTheComparisons(IEnumerable connections, IEnumerable
tables) +{ + foreach (var table in tables) + { + var sql = table.SqlSelect; + var dataLegacy = GetData(connections.First(), sql); + var dataUpdate = GetData(connections.Last(), sql); + + var legacy = dataLegacy.Rows; + var update = dataUpdate.Rows; + var idxCount = legacy.Count; + var compare = new List(); + var jsonColumns = tables.SingleOrDefault(t => t.SchemaTable == table.TableName)?.Json.ToList(); + foreach (var row in Enumerable.Range(0, idxCount)) + { + var r = legacy[row]; + if (row < update.Count) + { + var u = update[row]; + var rJson = JsonConvert.SerializeObject(r.ItemArray); + var uJson = JsonConvert.SerializeObject(u.ItemArray); + if (rJson != uJson) + { + if (jsonColumns == null) + { + compare.Add(new CompareSet(r, u)); + } + else + { + compare.Add(new CompareSet(r, u, jsonColumns)); + } + } + } + else + { + if (jsonColumns == null) + { + compare.Add(new CompareSet(r, null)); + } + else + { + compare.Add(new CompareSet(r, null, jsonColumns)); + } + } + } + if (compare.Any()) + { + compare.Dump(table.TableName, 3); + } + else + { + "No differences found in data".Dump($"{table.TableName} ({dataLegacy.Rows.Count} rows)"); + } + } +} + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + public IEnumerable TableNames { get; set; } + public ServerInstance(string server, string database, IEnumerable tableNames) + { + Server = server; + Database = database; + TableNames = tableNames; + } +} + +public DataTable GetData(ServerInstance serverInstance, string sql) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var datatable = new DataTable(); + var adapter = new SqlDataAdapter(sql, conn); + try + { + adapter.Fill(datatable); + } + catch (Exception ex) + { + sql.Dump(nameof(sql)); + throw; + } + var tableNames = serverInstance.TableNames; + var idx = 0; + foreach (var tableName in tableNames) + { + datatable.TableName = tableName; + idx += 1; + } + return datatable; + } +} + +public class CompareSet +{ + internal IList ColumnNames { get; set; } + internal IList Legacy { get; set; } + internal IList Update { get; set; } + public IList Rows { get; set; } + internal IList JsonColumns { get; set; } + public CompareSet(DataRow right, DataRow left) + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + Legacy = right.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + Rows = ColumnNames.Select((c, i) => new Row(c, Legacy[i], Update?[i])).ToList(); + } + public CompareSet(DataRow right, DataRow left, IList jsonColumns) + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + Legacy = right.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + JsonColumns = jsonColumns; + Rows = ColumnNames.Select((c, i) => new Row(c, Legacy[i], Update?[i], JsonColumns.Contains(c, StringComparer.CurrentCultureIgnoreCase))).ToList(); + } + +} + +public class Row +{ + public string Column; + public bool IsJson; + public object Left; + public object Right; + + public Row(string column, object left, object right) + { + Column = column; + Left = left; + Right = right; + } + + public Row(string column, object left, object right, bool isJson) + : this(column, left, right) + { + IsJson = isJson; + if (!isJson) return; + Left = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(left.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + if (right == null) return; + Right = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(right.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + + object ToDump() => new + { + Column = Left.Equals(Right ?? "") ? (object)Column : new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:lightyellow;color:black"), Column)), + Left, + Right + }; +} + +#endregion \ No newline at end of file diff --git a/Find string in table data.linq b/Find string in table data.linq new file mode 100644 index 0000000..26d19f6 --- /dev/null +++ b/Find string in table data.linq @@ -0,0 +1,98 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var searchFor = "Vice President"; + var sql = new List(); + foreach (var table in Mapping.GetTables()) + { + var columns = from dm in table.RowType.DataMembers + where dm.DbType != null && dm.DbType.Contains("Varchar") + select new { dm.Name, dm.DbType, dm.Type, dm.MappedName, dm.IsPrimaryKey }; + if (!columns.Any()) continue; + //columns.Dump(table.TableName); + sql.AddRange(columns.Select(x => $@"SELECT '{table.TableName}.{x.Name}' what, LEFT({table.TableName}.[{x.Name}], 3630) has + FROM {table.TableName} (NOLOCK) + WHERE {table.TableName}.[{x.Name}] LIKE '%{searchFor}%'")); + } + sql.ForEach(query => + { + try + { + var result = this.ExecuteQuery(query).ToList(); + if (result.Any()) + { + result.Select(r => r.has).Dump(result.First().what); + } + } + catch (Exception ex) + { + query.Dump(ex.Message); + } + }); +} + +public class Answer +{ + public string what { get; set; } + public string has { get; set; } +} \ No newline at end of file diff --git a/FiscalMonthResolver/Test FiscalMonthResolver.linq b/FiscalMonthResolver/Test FiscalMonthResolver.linq new file mode 100644 index 0000000..0e9e07f --- /dev/null +++ b/FiscalMonthResolver/Test FiscalMonthResolver.linq @@ -0,0 +1,184 @@ + + + eae63890-d1e5-4142-8086-9d954a38c63c + true + D0011-SQL-01.sdt.local + jazz tst Edward Elmhurst 20210127.1 + true + + System.Collections.ObjectModel + + +void Main() +{ + var fmr = new FiscalMonthResolver(from fm in DimFiscalMonths + select new FiscalMonth + { + MemberGUID = fm.MemberGUID, + FiscalMonthID = fm.FiscalMonthID, + SortOrder = fm.SortOrder, + FiscalMonthCode = int.Parse(fm.FiscalMonthCode), + Name = fm.Name, + Abbreviation = fm.Abbreviation, + DaysInMonth = fm.DaysInMonth, + YTDDaysInMonth = fm.YTDDaysInMonth, + QuarterID = fm.QuarterID, + MonthColumnName = fm.MonthColumnName, + TransactionID = fm.TransactionID, + DaysInLeapYearMonth = fm.DaysInLeapYearMonth, + YTDDaysInLeapYearMonth = fm.YTDDaysInLeapYearMonth, + IsReal = fm.IsReal + }); + + var config = new Configuration(fmr); + var fiscalMonths = fmr.AllFiscalMonths; + var startDate = new DateTime(2020, 1, 1); + var endDate = startDate.AddYears(1).AddDays(-1); + config.GetYearMonths(startDate, endDate).Dump(); + + startDate = config.GetFiscalYearStartDate(); + endDate = config.GetFiscalYearEndDate(); + config.GetYearMonths(startDate, endDate).Dump(); + fiscalMonths.Where(fm => fm.IsReal).Dump(); +} + +// Define other methods and classes here + +public class Configuration +{ + public int FiscalYearID = 2020; + public FiscalMonthResolver FiscalMonthResolver; + + public Configuration(FiscalMonthResolver fmr) + { + FiscalMonthResolver = fmr; + } + + public DateTime GetFiscalYearStartDate() + { + return GetFiscalYearEndDate().AddYears(-1).AddDays(1); + } + + public DateTime GetFiscalYearEndDate() + { + var lastFiscalMonth = FiscalMonthResolver.LastFiscalMonth.FiscalMonthID; + return new DateTime(FiscalYearID, lastFiscalMonth, DateTime.DaysInMonth(FiscalYearID, lastFiscalMonth)); + } + + public IList GetYearMonths(DateTime startDate, DateTime endDate) + { + var ym = new List(); + var currentMonth = startDate; + $"\r\nCurrent: {currentMonth:d} - End: {endDate:d}".Dump(); + while (currentMonth <= endDate) + { + var fiscalMonth = FiscalMonthResolver.ConvertToFiscalYearMonth(currentMonth); + fiscalMonth.Dump(); + ym.Add(new YearMonth(fiscalMonth.Year, currentMonth.Year, + FiscalMonthResolver.GetByFiscalMonthId(currentMonth.Month))); + currentMonth = currentMonth.AddMonths(1); + } + return ym; + } +} + +public interface IFiscalMonthResolver + +{ + FiscalMonth FirstFiscalMonth { get; } + + FiscalMonth LastFiscalMonth { get; } + + FiscalMonth GetByFiscalMonthId(int fiscalMonthId); + + FiscalMonth GetByFiscalMonthSortOrder(int sortOrder); + + List AllFiscalMonths { get; } +} + +public class FiscalMonthResolver : IFiscalMonthResolver +{ + public FiscalMonthResolver(IEnumerable fiscalMonths) + { + AllFiscalMonths = fiscalMonths.ToList(); + } + + public FiscalMonth FirstFiscalMonth => GetByFiscalMonthSortOrder(1); + + public FiscalMonth LastFiscalMonth => GetByFiscalMonthSortOrder(12); + + public List AllFiscalMonths { get; set; } + + public FiscalMonth GetByFiscalMonthId(int fiscalMonthId) + { + return AllFiscalMonths.FirstOrDefault(afm => afm.FiscalMonthID == fiscalMonthId); + } + + public FiscalMonth GetByFiscalMonthSortOrder(int sortOrder) + { + return AllFiscalMonths.FirstOrDefault(afm => afm.SortOrder == sortOrder); + } + + public DateTime ConvertToFiscalYearMonth(DateTime calendarYearMonth) + { + var fiscalYearID = calendarYearMonth.Month <= LastFiscalMonth.FiscalMonthID + ? calendarYearMonth.Year + : calendarYearMonth.Year + 1; + return new DateTime(fiscalYearID, calendarYearMonth.Month, 1); + } +} + +public class FiscalMonth +{ + internal Guid MemberGUID { get; set; } + public byte FiscalMonthID { get; set; } + public byte SortOrder { get; set; } + public int FiscalMonthCode { get; set; } + public String Name { get; set; } + public String Abbreviation { get; set; } + public Int32 DaysInMonth { get; set; } + public Int32 YTDDaysInMonth { get; set; } + public byte QuarterID { get; set; } + public String MonthColumnName { get; set; } + internal String Version { get; set; } + internal Guid HistoryItemGUID { get; set; } + internal Int32 TransactionID { get; set; } + public Int32 DaysInLeapYearMonth { get; set; } + public Int32 YTDDaysInLeapYearMonth { get; set; } + public Boolean IsReal { get; set; } + +} + +public class YearMonth +{ + public readonly int FiscalYear; + public readonly int CalendarYear; + + internal readonly FiscalMonth FiscalMonth; + + public readonly DateTime FiscalYearMonth; + + public readonly DateTime CalendarYearMonth; + + #region Helper Properties to corelate to database column names + + public int FiscalYearID => FiscalYear; + + /// + /// This is calendar month and FiscalMonth.SortOrder is the real FiscalMonth + /// we put it here so that we don't frikin confuse ourself between fiscalmonth and calendarmonth :x + /// + public int FiscalMonthID => FiscalMonth.FiscalMonthID; + + #endregion + + internal YearMonth(int fiscalYear, int calendarYear, FiscalMonth fiscalMonth) + { + FiscalYear = fiscalYear; + CalendarYear = calendarYear; + FiscalMonth = fiscalMonth; + + FiscalYearMonth = new DateTime(fiscalYear, fiscalMonth.SortOrder, 1); + CalendarYearMonth = new DateTime(calendarYear, fiscalMonth.FiscalMonthID, 1); + } +} \ No newline at end of file diff --git a/Fluent Assertion IAssertionRule Test.linq b/Fluent Assertion IAssertionRule Test.linq new file mode 100644 index 0000000..7d12cab --- /dev/null +++ b/Fluent Assertion IAssertionRule Test.linq @@ -0,0 +1,114 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + FluentAssertions + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + FluentAssertions.Equivalency + FluentAssertions.Execution + FluentAssertions + + +void Main() +{ + var lt = LoginType.Something; + Action act1 = () => + { + var ltDto = LoginTypeDto.Something; + ltDto.Should().BeEquivalentTo(lt, options => options.Using(new LoginTypeRule())); + }; + Action act2 = () => + { + var ltDto = LoginTypeDto.SomethingElse; + ltDto.Should().BeEquivalentTo(lt, options => options.Using(new LoginTypeRule())); + }; + act1.Should().NotThrow(); + act2.Should().Throw(); +} + +// Define other methods and classes here +public class LoginTypeRule : IAssertionRule +{ + public bool AssertEquality(IEquivalencyValidationContext context) + { + var subjectValue = GetValueForEnum(context.Subject); + var expectationValue = GetValueForEnum(context.Expectation); + + if (subjectValue == null || expectationValue == null) + { + // rule not applicable + return false; + } + + Execute.Assertion + .BecauseOf(context.Because, context.BecauseArgs) + .ForCondition(subjectValue == expectationValue) + .FailWith("Expected {context:string} to be {0}{reason}, but found {1}", + context.Subject, context.Expectation); + + // equality assertion handled + return true; + } + + private int? GetValueForEnum(object enumValue) + { + if (enumValue is LoginType || enumValue is LoginTypeDto) + { + return (int)enumValue; + } + return null; + } + +} + +enum LoginType { Something, SomethingElse, Other }; + +enum LoginTypeDto { Something, SomethingElse, Other } + diff --git a/Func Test.linq b/Func Test.linq new file mode 100644 index 0000000..ac69aff --- /dev/null +++ b/Func Test.linq @@ -0,0 +1,70 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +//Func f = (x => x + x); +var bb = new bool[] { false, true, true, false }; +var xx = new decimal[] { 1.0m, 0.0m, 3.0m, 4.0m }; +Func f = ((x,month) => bb[x] +? xx[x] == 0.0m + ? 1.0 : (double)month +: (double)month); +f(0,xx[3]).Dump(); +f(1,xx[2]).Dump(); \ No newline at end of file diff --git a/Get Report Parms.linq b/Get Report Parms.linq new file mode 100644 index 0000000..5b4c02d --- /dev/null +++ b/Get Report Parms.linq @@ -0,0 +1,83 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst StrataSphere 20191104.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var doc = new XmlDocument(); + var info = + from r in REReports + join p in REDSCubeReportParameters on r.ReportGUID equals p.ReportGUID into rdscrp + from p in rdscrp.DefaultIfEmpty() + join rp in REClientReportParameters on r.ReportGUID equals rp.ReportGUID into rcrp + from rp in rcrp.DefaultIfEmpty() + where r.Name.Contains("B-25227") + //where new[] { "B-25227" }.Contains(r.Name) + select new { Parameters = p == null ? rp.ParameterXML : p.ParameterXML, r }; + var test = info.ToList() + .ConvertAll(i => + { + doc.LoadXml(i.Parameters); + return new { i.r.Name, parameter = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented) }; + }); + test.Dump(); +} + +// Define other methods and classes here diff --git a/HackWeek AWS/AWS SDK Basics.linq b/HackWeek AWS/AWS SDK Basics.linq new file mode 100644 index 0000000..4e1a110 --- /dev/null +++ b/HackWeek AWS/AWS SDK Basics.linq @@ -0,0 +1,200 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var bucketName = "sdt-glue-hackweek"; + var crawlerName = "client1_input_icd10dx"; + + var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1); + var glueclient = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1); + + //UploadICDFiles(client, bucketName); + //ListBucket(client, bucketName).Dump("S3 Buckets"); + ListCrawlers(glueclient).Crawlers.Select(c => new + { + c.Name, + c.DatabaseName, + c.LastCrawl.Status, + c.LastCrawl.ErrorMessage, + c.Description, + c.Targets.S3Targets + }).Dump("Crawlers"); + /* + //RunCrawler(glueclient, crawlerName).Dump(); + glueclient.GetDatabases(new GetDatabasesRequest{}).DatabaseList.Dump("Database"); + glueclient.GetCrawler(new GetCrawlerRequest { Name = crawlerName}).Crawler.Dump("Crawler"); + glueclient.GetTables(new GetTablesRequest{DatabaseName = "glue-hackweek-icd"}).TableList.Dump("glue hackweek icd tables"); + */ +} + +// Define other methods and classes here + +void UploadICDFiles(AmazonS3Client client, string bucketName) +{ + var regex = new Regex("wfu_icd(10|9)_(dx|px)_(\\d*)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + var sourcePath = @"S:\Development\Cube Killers\Deidentified DI Import Files\Wake - Deidentified"; + var sourceFiles = "wfu_icd*.psv"; + var files = System.IO.Directory.GetFiles(sourcePath, sourceFiles).OrderBy(f => f); + files + //.Where(f => f.Contains("10_dx")) + //.Take(1) + .ToList().ForEach(f => + { + var fileName = Path.GetFileNameWithoutExtension(f); + var subdir = regex.Replace(fileName, "icd/icd$1/$2"); + var key = regex.Replace(fileName, "icd$1$2"); + TransferToBucketAsync(client, bucketName, subdir, key, f).Wait();//.Dump(); + }); +} + +ListObjectsResponse ListBucket(AmazonS3Client client, string bucketName) +{ + var request = new Amazon.S3.Model.ListObjectsRequest(); + return client.ListObjects(bucketName); +} + +ListObjectsResponse ListBucket(string accessKeyID, string secretKey, string bucketName) +{ + using (var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + return ListBucket(client, bucketName); + } +} + +static async Task TransferToBucketAsync(AmazonS3Client client, string bucketName, string subdirName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var utility = new TransferUtility(client); + var request = new TransferUtilityUploadRequest + { + BucketName = $"{bucketName}{(!string.IsNullOrEmpty(subdirName) ? @"/" + subdirName : "")}", + Key = keyName, + ContentType = "text/plain" + }; + request.FilePath = fileName; + await utility.UploadAsync(request); +} + +static async Task UploadToBucketAsync(AmazonS3Client client, string bucketName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var request = new Amazon.S3.Model.PutObjectRequest + { + BucketName = bucketName, + Key = keyName, + ContentBody = File.ReadAllText(fileName), + ContentType = "text/plain" + }; + request.FilePath = fileName; + return await client.PutObjectAsync(request); +} +PutObjectResponse UploadToBucket(AmazonS3Client client, string bucketName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var result = UploadToBucketAsync(client, bucketName, keyName, fileName); + result.Wait(); + return result.Result; +} + +PutObjectResponse UploadToBucket(string accessKeyID, string secretKey, string bucketName, string keyName, string fileName) +{ + using (var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + return UploadToBucket(client, bucketName, keyName, fileName); + } +} + +GetCrawlersResponse ListCrawlers(AmazonGlueClient client) +{ + return client.GetCrawlers(new GetCrawlersRequest()); +} + +GetCrawlersResponse ListCrawlers(string accessKeyID, string secretKey) +{ + + using (var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + var crawlerRequest = new GetCrawlersRequest(); + return client.GetCrawlers(crawlerRequest); + } +} + +StartCrawlerResponse RunCrawler(AmazonGlueClient client, string crawlerName) +{ + var crawler = new StartCrawlerRequest + { + Name = crawlerName + }; + return client.StartCrawler(crawler); +} + +StartCrawlerResponse RunCrawler(string accessKeyID, string secretKey, string crawlerName) +{ + + using (var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + var crawler = new StartCrawlerRequest + { + Name = crawlerName + }; + return client.StartCrawler(crawler); + } +} diff --git a/HackWeek AWS/HackWeek AWS Glue Bucket to Crawlers.linq b/HackWeek AWS/HackWeek AWS Glue Bucket to Crawlers.linq new file mode 100644 index 0000000..df27183 --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue Bucket to Crawlers.linq @@ -0,0 +1,142 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +//#define TRACE + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var bucketName = "sdt-glue-hackweek"; + + var s3 = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1); + + var s3Objects = bucketName.AWSListBucket(s3).S3Objects + .Where(so => so.Key.StartsWith("wfu/")); + s3Objects.Dump("S3 Objects"); + + //var crawlerName = "client1_input_icd10dx"; + + var glue = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1); + var dbs = glue.GetDatabases(new GetDatabasesRequest()).DatabaseList.Select(dl => dl.Name); + var myDBName = "glue-hackweek-thom"; + if (dbs.Contains(myDBName)) + { + glue.DeleteDatabase(new DeleteDatabaseRequest { Name = myDBName }); + } + glue.CreateDatabase(new CreateDatabaseRequest { DatabaseInput = new DatabaseInput { Name = myDBName, Description = "Thom's Glue Hackweek DB" } }); + var crawlers = glue.ListCrawlers(new ListCrawlersRequest()).CrawlerNames; + var tasks = new List>(); + crawlers.Where(c => c.StartsWith("wfu_")).ToList() + .ForEach(c => + { + try + { + glue.DeleteCrawler(new DeleteCrawlerRequest { Name = c }); + } + catch (EntityNotFoundException ex) + { + ex.Message.Dump(); + } + }); + crawlers = glue.ListCrawlers(new ListCrawlersRequest()).CrawlerNames; + + var tags = new[] { new { key = "environment", value = "hackweek" } }.ToDictionary(dl => dl.key, dl => dl.value); + var newCrawlers = s3Objects.ToList() + .ConvertAll(o => new CreateCrawlerRequest + { + Classifiers = new[] { "client1-input-psv" }.ToList(), + Configuration = @"{""Version"":1.0,""CrawlerOutput"":{""Partitions"":{""AddOrUpdateBehavior"":""InheritFromTable""}}}", + DatabaseName = myDBName, + Name = string.Join("_", o.Key.Split('/').TakeAllButLast()), + Role = "hackday-glue-role-team2", + SchemaChangePolicy = new SchemaChangePolicy + { + DeleteBehavior = new DeleteBehavior("LOG"), + UpdateBehavior = new UpdateBehavior("UPDATE_IN_DATABASE") + }, + TablePrefix = string.Join("_", o.Key.Split('/').TakeAllButLast().TakeAllButLast()) + "_", + Tags = tags, + Targets = new CrawlerTargets + { + S3Targets = new List { + new S3Target { Path = $"s3://{o.BucketName}/{string.Join("/", o.Key.Split('/').TakeAllButLast())}" } + } + } + }).OrderBy(o => o.Name).ToList(); + newCrawlers.Dump("New Crawlers"); + newCrawlers.ForEach(c => + { + try + { + tasks.Add(glue.CreateCrawlerAsync(c, new CancellationToken())); + } + catch (AmazonGlueException ex) + { + ex.Dump($"Glue Exception {c.Name}"); + } + }); + while (tasks.Any(t => !t.IsCompleted)) + { + } + var runtasks = new List>(); + newCrawlers.ForEach(c => runtasks.Add(glue.StartCrawlerAsync(new StartCrawlerRequest { Name = c.Name }))); + runtasks.Dump("Run Tasks"); +} + +// Define other methods and classes here \ No newline at end of file diff --git a/HackWeek AWS/HackWeek AWS Glue Create Crawler on the fly.linq b/HackWeek AWS/HackWeek AWS Glue Create Crawler on the fly.linq new file mode 100644 index 0000000..f54dcdd --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue Create Crawler on the fly.linq @@ -0,0 +1,77 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var crawlerName = "client1_input_icd10dx"; + + var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1); + var regex = new Regex("(icd_?)(10)"); + + var crawler = client.GetCrawler(new GetCrawlerRequest { Name = crawlerName }).Crawler; + var newCrawler = JsonConvert.DeserializeObject(regex.Replace(JsonConvert.SerializeObject(crawler), "${1}9")); + //newCrawler.LastCrawl = null; + crawler.Dump("Crawler"); + newCrawler.Dump("New Crawler"); + var result = client.CreateCrawler(newCrawler); + result.Dump(); +} + +// Define other methods and classes here diff --git a/HackWeek AWS/HackWeek AWS Glue List Bucket.linq b/HackWeek AWS/HackWeek AWS Glue List Bucket.linq new file mode 100644 index 0000000..86c0c23 --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue List Bucket.linq @@ -0,0 +1,70 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var bucketName = "sdt-glue-hackweek"; + + var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1); + + bucketName.AWSListBucket(client).S3Objects.Dump("S3 Objects"); +} + +// Define other methods and classes here diff --git a/HackWeek AWS/HackWeek AWS Glue List Crawlers.linq b/HackWeek AWS/HackWeek AWS Glue List Crawlers.linq new file mode 100644 index 0000000..8ab550d --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue List Crawlers.linq @@ -0,0 +1,201 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var bucketName = "sdt-glue-hackweek"; + var crawlerName = "client1_input_icd10dx"; + + var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1); + var glueclient = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1); + + //UploadICDFiles(client, bucketName); + //ListBucket(client, bucketName).Dump("S3 Buckets"); + ListCrawlers(glueclient).Crawlers.Select(c => new + { + c.Name, + c.DatabaseName, + c.LastCrawl.Status, + c.LastCrawl.ErrorMessage, + c.Description, + c.Targets.S3Targets + }).Dump("Crawlers"); + /* + //RunCrawler(glueclient, crawlerName).Dump(); + glueclient.GetDatabases(new GetDatabasesRequest{}).DatabaseList.Dump("Database"); + glueclient.GetCrawler(new GetCrawlerRequest { Name = crawlerName}).Crawler.Dump("Crawler"); + glueclient.GetTables(new GetTablesRequest{DatabaseName = "glue-hackweek-icd"}).TableList.Dump("glue hackweek icd tables"); + */ +} + +// Define other methods and classes here + +void UploadICDFiles(AmazonS3Client client, string bucketName) +{ + var regex = new Regex("wfu_icd(10|9)_(dx|px)_(\\d*)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + var sourcePath = @"S:\Development\Cube Killers\Deidentified DI Import Files\Wake - Deidentified"; + var sourceFiles = "wfu_icd*.psv"; + var files = System.IO.Directory.GetFiles(sourcePath, sourceFiles).OrderBy(f => f); + files + //.Where(f => f.Contains("10_dx")) + //.Take(1) + .ToList().ForEach(f => + { + var fileName = Path.GetFileNameWithoutExtension(f); + var subdir = regex.Replace(fileName, "icd/icd$1/$2"); + var key = regex.Replace(fileName, "icd$1$2"); + TransferToBucketAsync(client, bucketName, subdir, key, f).Wait();//.Dump(); + }); +} + +ListObjectsResponse ListBucket(AmazonS3Client client, string bucketName) +{ + var request = new Amazon.S3.Model.ListObjectsRequest(); + return client.ListObjects(bucketName); +} + +ListObjectsResponse ListBucket(string accessKeyID, string secretKey, string bucketName) +{ + using (var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + return ListBucket(client, bucketName); + } +} + +static async Task TransferToBucketAsync(AmazonS3Client client, string bucketName, string subdirName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var utility = new TransferUtility(client); + var request = new TransferUtilityUploadRequest + { + BucketName = $"{bucketName}{(!string.IsNullOrEmpty(subdirName) ? @"/" + subdirName : "")}", + Key = keyName, + ContentType = "text/plain" + }; + request.FilePath = fileName; + await utility.UploadAsync(request); +} + +static async Task UploadToBucketAsync(AmazonS3Client client, string bucketName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var request = new Amazon.S3.Model.PutObjectRequest + { + BucketName = bucketName, + Key = keyName, + ContentBody = File.ReadAllText(fileName), + ContentType = "text/plain" + }; + request.FilePath = fileName; + return await client.PutObjectAsync(request); +} + +PutObjectResponse UploadToBucket(AmazonS3Client client, string bucketName, string keyName, string fileName) +{ + new { keyName, fileName }.Dump(); + var result = UploadToBucketAsync(client, bucketName, keyName, fileName); + result.Wait(); + return result.Result; +} + +PutObjectResponse UploadToBucket(string accessKeyID, string secretKey, string bucketName, string keyName, string fileName) +{ + using (var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + return UploadToBucket(client, bucketName, keyName, fileName); + } +} + +GetCrawlersResponse ListCrawlers(AmazonGlueClient client) +{ + return client.GetCrawlers(new GetCrawlersRequest()); +} + +GetCrawlersResponse ListCrawlers(string accessKeyID, string secretKey) +{ + + using (var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + var crawlerRequest = new GetCrawlersRequest(); + return client.GetCrawlers(crawlerRequest); + } +} + +StartCrawlerResponse RunCrawler(AmazonGlueClient client, string crawlerName) +{ + var crawler = new StartCrawlerRequest + { + Name = crawlerName + }; + return client.StartCrawler(crawler); +} + +StartCrawlerResponse RunCrawler(string accessKeyID, string secretKey, string crawlerName) +{ + + using (var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1)) + { + var crawler = new StartCrawlerRequest + { + Name = crawlerName + }; + return client.StartCrawler(crawler); + } +} diff --git a/HackWeek AWS/HackWeek AWS Glue Run Crawlers.linq b/HackWeek AWS/HackWeek AWS Glue Run Crawlers.linq new file mode 100644 index 0000000..fd580ee --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue Run Crawlers.linq @@ -0,0 +1,70 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.Glue + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Amazon.Glue + Amazon.Glue.Model + System.Threading.Tasks + + +void Main() +{ + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var crawlerNames = new[] { "client1_input_icd10dx", "client1_input_icd10px"}; + + var client = new AmazonGlueClient(accessKeyID, secretKey, RegionEndpoint.USEast1); + + crawlerNames.ToList().ForEach(crawlerName => crawlerName.RunCrawler(client).Dump($"{crawlerName}")); +} + +// Define other methods and classes here diff --git a/HackWeek AWS/HackWeek AWS Glue Upload Files to S3.linq b/HackWeek AWS/HackWeek AWS Glue Upload Files to S3.linq new file mode 100644 index 0000000..1da5339 --- /dev/null +++ b/HackWeek AWS/HackWeek AWS Glue Upload Files to S3.linq @@ -0,0 +1,87 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var sourcePath = @"S:\Development\Cube Killers\Deidentified DI Import Files\Wake - Deidentified"; + var files = Directory.GetFiles(sourcePath, "wfu*.*"); + var uploads = files.Select(f => + { + var s3Name = Regex.Replace(Path.GetFileNameWithoutExtension(f).Replace("_", "/"), @"^(.*)/[\d]{8}$", "${1}"); + var subdir = string.Join("/", s3Name.Split('/').TakeAllButLast()); + var keyName = s3Name.Split('/').Last(); + return new + { + fullName = f, + fileName = Path.GetFileNameWithoutExtension(f), + s3Name, + subdir, + keyName + }; + }); + + uploads.Dump("Uploads"); + var accessKeyID = Util.GetPassword("aws.sdt-tlamb.accessid"); + var secretKey = Util.GetPassword("aws.sdt-tlamb.secretid"); + var bucketName = "sdt-glue-hackweek"; + + var client = new AmazonS3Client(accessKeyID, secretKey, RegionEndpoint.USEast1); + var oldFiles = bucketName.AWSListBucket(client).S3Objects.Where(f => f.Key.StartsWith("wfu/")).ToList(); + oldFiles.ForEach(f => client.DeleteObject(bucketName, f.Key)); + bucketName.AWSListBucket(client).S3Objects.Dump("Before"); + uploads.ToList().ForEach(u => u.fullName.AWSUploadAsync(client, bucketName, u.keyName, u.s3Name)); + bucketName.AWSListBucket(client).S3Objects.Dump("After"); +} + +// Define other methods and classes here diff --git a/Heatmap Facility Deaths.linq b/Heatmap Facility Deaths.linq new file mode 100644 index 0000000..309b04d --- /dev/null +++ b/Heatmap Facility Deaths.linq @@ -0,0 +1,58 @@ + + + ce6f5caf-a955-42be-a634-5eb79966aca4 + true + D0017-SQL-01.sdt.local + jazz tst Aurora 20160126.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + + +var dataRun = from i in ((from fpes in FactPatientEncounterSummaries +where fpes.DischargeDateTime > fpes.AdmitDateTime +&& fpes.DateofDeath >= fpes.AdmitDateTime +&& fpes.DateofDeath >= fpes.DischargeDateTime.AddDays(-30) && fpes.DateofDeath <= fpes.DischargeDateTime.AddDays(30) +&& fpes.AdmitDateTime >= new DateTime(2015,1,1) +select new { fpes.FiscalYearID, fpes.EntityID, fpes.FacilityID, fpes.AttendPhysicianID, fpes.PrimaryPhysicianID, fpes.MSDRGCaseTypeFamilyID +, fpes.AdmitDateTime, fpes.DischargeDateTime, fpes.DateofDeath, fpes.PatientID, fpes.LengthOfStay }) +.Take(10000)) +group i by new { i.FiscalYearID, i.EntityID, i.FacilityID +, i.AttendPhysicianID +, i.PrimaryPhysicianID +, AdmitDateTimeYr = i.AdmitDateTime.Year +, AdmitDateTimeMo = i.AdmitDateTime.Month +, CaseTypeFamilyID= i.MSDRGCaseTypeFamilyID +, DischargeDateTimeYr = i.DischargeDateTime.Year +, DischargeDateTimeMo = i.DischargeDateTime.Month +, DateofDeathYr = i.DateofDeath.Year +, DateofDeathMo = i.DateofDeath.Month +} into g +select new { g.Key.FiscalYearID, g.Key.EntityID, g.Key.FacilityID +, g.Key.AttendPhysicianID +, g.Key.PrimaryPhysicianID +, g.Key.AdmitDateTimeYr +, g.Key.AdmitDateTimeMo +, g.Key.CaseTypeFamilyID +, g.Key.DischargeDateTimeYr +, g.Key.DischargeDateTimeMo +, g.Key.DateofDeathYr +, g.Key.DateofDeathMo +, MinDeath = (int)g.Min(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, MaxDeath = (int)g.Max(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, AvgDeath = (int)g.Average(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, DeceasedPatients = g.Count() +, AvgLOS = (int)g.Average(rl => rl.LengthOfStay) } +; + +(from data in dataRun +join de in Clientdss_DimEntities on data.EntityID equals de.EntityID +group data by new { data.EntityID, de.Name } into g +orderby g.Key.EntityID +select new { g.Key.EntityID, g.Key.Name, DeceasedPatients = g.Sum(rl => rl.DeceasedPatients) }).Dump(); + diff --git a/Heatmap Raw Data.linq b/Heatmap Raw Data.linq new file mode 100644 index 0000000..c104536 --- /dev/null +++ b/Heatmap Raw Data.linq @@ -0,0 +1,111 @@ + + + ce6f5caf-a955-42be-a634-5eb79966aca4 + true + D0017-SQL-01.sdt.local + jazz tst Aurora 20160126.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + + +var dataRun = from i in ( + (from fpes in FactPatientEncounterSummaries + where fpes.DischargeDateTime > fpes.AdmitDateTime + && fpes.DateofDeath >= fpes.AdmitDateTime + && fpes.DateofDeath >= fpes.DischargeDateTime.AddDays(-30) && fpes.DateofDeath <= fpes.DischargeDateTime.AddDays(30) + && fpes.AdmitDateTime >= new DateTime(2015,1,1) + select new { fpes.FiscalYearID, fpes.EntityID, fpes.FacilityID, fpes.AttendPhysicianID, fpes.PrimaryPhysicianID, fpes.MSDRGCaseTypeFamilyID + , fpes.AdmitDateTime, fpes.DischargeDateTime, fpes.DateofDeath, fpes.PatientID, fpes.LengthOfStay }) + .Take(10000) +) +group i by new { i.FiscalYearID, i.EntityID, i.FacilityID +, i.AttendPhysicianID +, i.PrimaryPhysicianID +, AdmitDateTimeYr = i.AdmitDateTime.Year +, AdmitDateTimeMo = i.AdmitDateTime.Month +, CaseTypeFamilyID= i.MSDRGCaseTypeFamilyID +, DischargeDateTimeYr = i.DischargeDateTime.Year +, DischargeDateTimeMo = i.DischargeDateTime.Month +, DateofDeathYr = i.DateofDeath.Year +, DateofDeathMo = i.DateofDeath.Month +} into g +join de in Clientdss_DimEntities on g.Key.EntityID equals de.EntityID +join df in DimFacilities on g.Key.FacilityID equals df.FacilityID +join dpAttend in DimPhysicians on g.Key.AttendPhysicianID equals dpAttend.PhysicianID +join dpPrimary in DimPhysicians on g.Key.PrimaryPhysicianID equals dpPrimary.PhysicianID +join ctf in CaseTypeFamilies on g.Key.CaseTypeFamilyID equals ctf.CaseTypeFamilyID +orderby g.Key.FiscalYearID, g.Key.EntityID, g.Key.FacilityID +select new { g.Key.FiscalYearID +//, g.Key.EntityID +, Entity = de.Name +//, g.Key.FacilityID +, Facility = df.Name +//, g.Key.AttendPhysicianID +, Attenring = dpAttend.Physician +//, g.Key.PrimaryPhysicianID +, Primary = dpPrimary.Physician +, CaseTypeFamily = ctf.Name +, g.Key.AdmitDateTimeYr +, g.Key.AdmitDateTimeMo +, g.Key.CaseTypeFamilyID +, g.Key.DischargeDateTimeYr +, g.Key.DischargeDateTimeMo +, g.Key.DateofDeathYr +, g.Key.DateofDeathMo +, MinDeath = (int)g.Min(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, MaxDeath = (int)g.Max(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, AvgDeath = (int)g.Average(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, DeceasedPatients = g.Count() +, AvgLOS = (int)g.Average(rl => rl.LengthOfStay) } +; + +dataRun.Dump(); +/* +(from i in (from data in dataRun group data by new { data.AttendPhysicianID } into g select g.First()) +join dp in DimPhysicians on i.AttendPhysicianID equals dp.PhysicianID +orderby i.AttendPhysicianID +select new { i.AttendPhysicianID, Attending = dp.Physician }).Dump(); + +(from i in (from data in dataRun group data by new { data.PrimaryPhysicianID } into g select g.First()) +join dp in DimPhysicians on i.PrimaryPhysicianID equals dp.PhysicianID +orderby i.PrimaryPhysicianID +select new { i.PrimaryPhysicianID, Primary = dp.Physician }).Dump(); + +(from i in (from data in dataRun group data by new { data.CaseTypeFamilyID } into g select g.First()) +join ctf in CaseTypeFamilies on i.CaseTypeFamilyID equals ctf.CaseTypeFamilyID +orderby i.CaseTypeFamilyID +select new { i.CaseTypeFamilyID, CaseTypeFamily = ctf.Name }).Dump(); + +var result = +from data in dataRun +join de in Clientdss_DimEntities on data.EntityID equals de.EntityID +join df in DimFacilities on data.FacilityID equals df.FacilityID +join dpAttend in DimPhysicians on data.AttendPhysicianID equals dpAttend.PhysicianID +join dpPrimary in DimPhysicians on data.PrimaryPhysicianID equals dpPrimary.PhysicianID +join ctf in CaseTypeFamilies on data.CaseTypeFamilyID equals ctf.CaseTypeFamilyID +orderby data.FiscalYearID, data.EntityID, data.FacilityID, data.AdmitDateTimeYr, data.AdmitDateTimeMo, data.CaseTypeFamilyID +select new { data.FiscalYearID, data.EntityID +, Entity = de.Name +, data.FacilityID +, Facility = df.Name +, data.AttendPhysicianID +, Attending = dpAttend.Physician +, data.PrimaryPhysicianID +, Primary = dpPrimary.Physician +, AdmitDate = $"{data.AdmitDateTimeYr:0000}/{data.AdmitDateTimeMo:00}" +, data.CaseTypeFamilyID +, CaseTypeFamily = ctf.Name +, DischargeDate = $"{data.DischargeDateTimeYr:0000}/{data.DischargeDateTimeMo:00}" +, DateOfDeath = $"{data.DateofDeathYr:0000}/{data.DateofDeathMo:00}" +, data.MinDeath +, data.MaxDeath +, data.AvgDeath +, data.DeceasedPatients +, data.AvgLOS}; +*/ diff --git a/Heatmp Data Linq2Sql.linq b/Heatmp Data Linq2Sql.linq new file mode 100644 index 0000000..3ab0dab --- /dev/null +++ b/Heatmp Data Linq2Sql.linq @@ -0,0 +1,105 @@ + + + ce6f5caf-a955-42be-a634-5eb79966aca4 + true + D0017-SQL-01.sdt.local + jazz tst Aurora 20160126.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + + +var dataRun = from i in ((from fpes in FactPatientEncounterSummaries +where fpes.DischargeDateTime > fpes.AdmitDateTime +&& fpes.DateofDeath >= fpes.AdmitDateTime +&& fpes.DateofDeath >= fpes.DischargeDateTime.AddDays(-30) && fpes.DateofDeath <= fpes.DischargeDateTime.AddDays(30) +&& fpes.AdmitDateTime >= new DateTime(2015,1,1) +select new { fpes.FiscalYearID, fpes.EntityID, fpes.FacilityID, fpes.AttendPhysicianID, fpes.PrimaryPhysicianID, fpes.MSDRGCaseTypeFamilyID +, fpes.AdmitDateTime, fpes.DischargeDateTime, fpes.DateofDeath, fpes.PatientID, fpes.LengthOfStay }) +.Take(10000)) +group i by new { i.FiscalYearID, i.EntityID, i.FacilityID +, i.AttendPhysicianID +, i.PrimaryPhysicianID +, AdmitDateTimeYr = i.AdmitDateTime.Year +, AdmitDateTimeMo = i.AdmitDateTime.Month +, CaseTypeFamilyID= i.MSDRGCaseTypeFamilyID +, DischargeDateTimeYr = i.DischargeDateTime.Year +, DischargeDateTimeMo = i.DischargeDateTime.Month +, DateofDeathYr = i.DateofDeath.Year +, DateofDeathMo = i.DateofDeath.Month +} into g +select new { g.Key.FiscalYearID, g.Key.EntityID, g.Key.FacilityID +, g.Key.AttendPhysicianID +, g.Key.PrimaryPhysicianID +, g.Key.AdmitDateTimeYr +, g.Key.AdmitDateTimeMo +, g.Key.CaseTypeFamilyID +, g.Key.DischargeDateTimeYr +, g.Key.DischargeDateTimeMo +, g.Key.DateofDeathYr +, g.Key.DateofDeathMo +, MinDeath = (int)g.Min(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, MaxDeath = (int)g.Max(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, AvgDeath = (int)g.Average(rl => Math.Abs((rl.DateofDeath - rl.DischargeDateTime).TotalDays)) +, DeceasedPatients = g.Count() +, AvgLOS = (int)g.Average(rl => rl.LengthOfStay) } +; + +(from i in (from data in dataRun group data by new { data.EntityID } into g select g.First()) +join de in Clientdss_DimEntities on i.EntityID equals de.EntityID +orderby i.EntityID +select new { i.EntityID, Entity = de.Name }).Dump(); + +(from i in (from data in dataRun group data by new { data.FacilityID } into g select g.First()) +join df in DimFacilities on i.FacilityID equals df.FacilityID +orderby i.FacilityID +select new { i.FacilityID, Facility = df.Name }).Dump(); + +(from i in (from data in dataRun group data by new { data.AttendPhysicianID } into g select g.First()) +join dp in DimPhysicians on i.AttendPhysicianID equals dp.PhysicianID +orderby i.AttendPhysicianID +select new { i.AttendPhysicianID, Attending = dp.Physician }).Dump(); + +(from i in (from data in dataRun group data by new { data.PrimaryPhysicianID } into g select g.First()) +join dp in DimPhysicians on i.PrimaryPhysicianID equals dp.PhysicianID +orderby i.PrimaryPhysicianID +select new { i.PrimaryPhysicianID, Primary = dp.Physician }).Dump(); + +(from i in (from data in dataRun group data by new { data.CaseTypeFamilyID } into g select g.First()) +join ctf in CaseTypeFamilies on i.CaseTypeFamilyID equals ctf.CaseTypeFamilyID +orderby i.CaseTypeFamilyID +select new { i.CaseTypeFamilyID, CaseTypeFamily = ctf.Name }).Dump(); + +var result = +from data in dataRun +join de in Clientdss_DimEntities on data.EntityID equals de.EntityID +join df in DimFacilities on data.FacilityID equals df.FacilityID +join dpAttend in DimPhysicians on data.AttendPhysicianID equals dpAttend.PhysicianID +join dpPrimary in DimPhysicians on data.PrimaryPhysicianID equals dpPrimary.PhysicianID +join ctf in CaseTypeFamilies on data.CaseTypeFamilyID equals ctf.CaseTypeFamilyID +orderby data.FiscalYearID, data.EntityID, data.FacilityID, data.AdmitDateTimeYr, data.AdmitDateTimeMo, data.CaseTypeFamilyID +select new { data.FiscalYearID, data.EntityID +, Entity = de.Name +, data.FacilityID +, Facility = df.Name +, data.AttendPhysicianID +, Attending = dpAttend.Physician +, data.PrimaryPhysicianID +, Primary = dpPrimary.Physician +, AdmitDate = $"{data.AdmitDateTimeYr:0000}/{data.AdmitDateTimeMo:00}" +, data.CaseTypeFamilyID +, CaseTypeFamily = ctf.Name +, DischargeDate = $"{data.DischargeDateTimeYr:0000}/{data.DischargeDateTimeMo:00}" +, DateOfDeath = $"{data.DateofDeathYr:0000}/{data.DateofDeathMo:00}" +, data.MinDeath +, data.MaxDeath +, data.AvgDeath +, data.DeceasedPatients +, data.AvgLOS}; + +result.Dump(); \ No newline at end of file diff --git a/Information Schema.linq b/Information Schema.linq new file mode 100644 index 0000000..6fc885c --- /dev/null +++ b/Information Schema.linq @@ -0,0 +1,140 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.Runtime.Remoting.Contexts + + +void Main() +{ + GetColumns(); +} + +public void GetSchema() +{ + var schemata = ExecuteQuery("select * from Information_Schema.SCHEMATA") + .GroupBy(g => g.CATALOG_NAME, (Key, Data) => new { Key, Data = Data.OrderBy(d => d.SCHEMA_OWNER).ThenBy(d => d.SCHEMA_NAME).ToList() }) + .OrderBy(grp => grp.Key) + .ToList(); + schemata.Dump(); +} + +public void GetTables(string schema = null) +{ + var tables = ExecuteQuery
($"select * from Information_Schema.TABLES AS t WHERE t.TABLE_SCHEMA = '{schema}'") + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_TYPE }, + (Key, Tables) => new { Schema = Key.TABLE_SCHEMA, Type = Key.TABLE_TYPE, Tables = Tables.Select(ta => ta.TABLE_NAME).OrderBy(ta => ta).ToList() }); + tables.Dump(); +} + +public void GetColumns(string schema = null) +{ + // var tableDefs = tables.Where(t => t.Schema == schema).SelectMany(t => t.Tables.Select(ta => + // ExecuteQuery($"select * from Information_Schema.COLUMNS AS c WHERE c.TABLE_SCHEMA = '{t.Schema}' AND c.TABLE_NAME = '{ta}'"))); + var tableDefs = ExecuteQuery($"select * from Information_Schema.COLUMNS AS c") + .GroupBy(c => new Table {TABLE_CATALOG= c.TABLE_CATALOG, TABLE_SCHEMA = c.TABLE_SCHEMA, TABLE_TYPE = c.TABLE_NAME }, + (Key, Columns) => new { Key, Columns = Columns.OrderBy(c => c.ORDINAL_POSITION).ToList() }) + .OrderBy(c => c.Key.TABLE_CATALOG) + .ThenBy(c => c.Key.TABLE_SCHEMA) + .ThenBy(c => c.Key.TABLE_NAME); + tableDefs.Dump(); +} + +// Define other methods and classes here +public class Schemata +{ + public string CATALOG_NAME { get; set; } + public string SCHEMA_NAME { get; set; } + public string SCHEMA_OWNER { get; set; } +} + +public class Table +{ + public string TABLE_CATALOG { get; set; } + public string TABLE_SCHEMA { get; set; } + public string TABLE_NAME { get; set; } + public string TABLE_TYPE { get; set; } +} + +public class TableColumn +{ + public string TABLE_CATALOG { get; set; } + public string TABLE_SCHEMA { get; set; } + public string TABLE_NAME { get; set; } + public string COLUMN_NAME { get; set; } + public int? ORDINAL_POSITION { get; set; } + public string COLUMN_DEFAULT { get; set; } + public string IS_NULLABLE { get; set; } + public string DATA_TYPE { get; set; } + public int? CHARACTER_MAXIMUM_LENGTH { get; set; } + public int? CHARACTER_OCTET_LENGTH { get; set; } + public byte? NUMERIC_PRECISION { get; set; } + public short? NUMERIC_PRECISION_RADIX { get; set; } + public int? NUMERIC_SCALE { get; set; } + public short? DATETIME_PRECISION { get; set; } + public string CHARACTER_SET_CATALOG { get; set; } + public string CHARACTER_SET_SCHEMA { get; set; } + public string CHARACTER_SET_NAME { get; set; } + public string COLLATION_CATALOG { get; set; } + public string COLLATION_SCHEMA { get; set; } + public string COLLATION_NAME { get; set; } + public string DOMAIN_CATALOG { get; set; } + public string DOMAIN_SCHEMA { get; set; } + public string DOMAIN_NAME { get; set; } +} + diff --git a/JAZZ-10828 CTF Definitions/Convert CSV file to CTF definitions.linq b/JAZZ-10828 CTF Definitions/Convert CSV file to CTF definitions.linq new file mode 100644 index 0000000..d0f36f9 --- /dev/null +++ b/JAZZ-10828 CTF Definitions/Convert CSV file to CTF definitions.linq @@ -0,0 +1,111 @@ + + + 580b3b8d-cc02-4a68-8fbd-d1ec374a25f2 + true + D0001-sql-11.sdt.local + jazz dev master Prod + true + + LinqToCsv + LINQtoCSV + + +void Main() +{ + var path = @"D:\Users\tlamb\Downloads"; + var fileName = @"FY2020 New Codes_04242020_Final.csv"; + + var filePath = Path.Combine(path, fileName); + if (!File.Exists(filePath)) return; + + //var data = File.ReadAllLines(filePath); + //data.Dump(); + + var inputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', + FirstLineHasColumnNames = true + }; + + var ctfVersion = CaseTypeFamilyVersions.Any(x => x.Name.Equals("2019 Standard Mapping")) + ? (from x in CaseTypeFamilyVersions + where x.Name.Equals("2019 Standard Mappings") + select x.CaseTypeFamilyVersionID).FirstOrDefault() + : 2; + //ctfVersion.Dump(); + + var cc = new CsvContext(); + var dat = from x in cc.Read(filePath, inputFileDescription) + select new + { + ctfVersion, + x.Column1, + x.MS_DRG_Code, + x.MDC, + x.ICD10Code, + x.ICD10_Code_Description, + x.Code_Type_1DX_3PX, + Exclusion_Type = (x.Exclusion_Type == "N"), + x.DRGs_to_CTFs, + ICD_Needs_Review = (x.ICD_Needs_Review != "#N/A"), + x.CTF_Type, + Same_Type = (x.Same_Type == "Yes"), + CTF_To_Assign_Existing = (x.CTF_To_Assign_Existing ?? "").Replace("&", "And"), + New_CTF = ((x.New_CTF ?? "No") == "Yes") + }; + //dat.Dump(); + + var xCTF_To_Assign = dat.Select(d => d.CTF_To_Assign_Existing).Distinct(); + var ctf = CaseTypeFamilies + .Where(c => xCTF_To_Assign.Contains(c.Name)) + .GroupBy(c => c.Name, (g, d) => new { name = g, ids = d.Select(x => x.CaseTypeFamilyID).ToList() }) + .ToDictionary(c => c.name, c => c.ids); + //ctf.Aggregate("", (x, y) => $"{x}\r\nUNION\r\nSelect Name, Case Name when '{y.Key}' THEN 1 ELSE 0 END isMatch from dss.CaseTypeFamily where CaseTypeFamilyID = {y.Value.First()}").Substring(9) .Dump(); + + var msDrg = dat + .Where(d => !string.IsNullOrEmpty(d.ICD10Code)) + .ToList() + .ConvertAll(d => + { + var caseTypeFamilyID = ctf.TryGetValue(d.CTF_To_Assign_Existing, out var value) + ? value.FirstOrDefault() + : 0; + return new + { + CaseTypeFamilyID = caseTypeFamilyID, + CTFExisting = d.CTF_To_Assign_Existing, + SkipICD = false, + ICD10Code = d.ICD10Code.Replace(".",""), + MSDRGCode = d.MS_DRG_Code, + CaseTypeFamilyVersionID = d.ctfVersion + }; + }) + //.Where(d => d.ICD10Code.Contains(".")) + .Aggregate("", (x, y) => $@"{x} + +INSERT INTO dss.CaseTypeFamilyMappingICD10 +( CaseTypeFamilyID, SkipICD, ICD10Code, MSDRGCode, CaseTypeFamilyVersionID ) +SELECT ctf.CaseTypeFamilyID,{(y.SkipICD ? 1 : 0)},'{y.ICD10Code}','{y.MSDRGCode}',{y.CaseTypeFamilyVersionID} +FROM dss.CaseTypeFamily ctf +WHERE ctf.Name = '{y.CTFExisting}'") + .Substring(4); + msDrg.Dump(); +} + +// Define other methods and classes here +public class CTFDefinitions +{ + public string Column1 { get; set; } + public string MS_DRG_Code { get; set; } + public string MDC { get; set; } + public string ICD10Code { get; set; } + public string ICD10_Code_Description { get; set; } + public string Code_Type_1DX_3PX { get; set; } + public string Exclusion_Type { get; set; } + public string DRGs_to_CTFs { get; set; } + public string ICD_Needs_Review { get; set; } + public string CTF_Type { get; set; } + public string Same_Type { get; set; } + public string CTF_To_Assign_Existing { get; set; } + public string New_CTF { get; set; } +} diff --git a/JAZZ-14426 Create SQL.linq b/JAZZ-14426 Create SQL.linq new file mode 100644 index 0000000..6ddccbf --- /dev/null +++ b/JAZZ-14426 Create SQL.linq @@ -0,0 +1,79 @@ + + + bd4e97c5-84e7-4c61-80ca-8d53d7876af2 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + System.Globalization + + +void Main() +{ + var ti = CultureInfo.CurrentCulture.TextInfo; + var _2020MSDRGs = (from x in DimMSDRGs where x.DRGSchema == "2020MSDRG" select x.MSDRGCode).Distinct(); + var _caseTypeFamilyMappingICD10 = (from x in CaseTypeFamilyMappingICD10s select x.MSDRGCode).Distinct(); + var _ctfGlobalID = (from x in CaseTypeFamilies where x.CaseTypeFamilyGlobalID.StartsWith("M-") select x.CaseTypeFamilyGlobalID) + .ToList() + .Where(x => Regex.IsMatch(x, @"M-\d+")) + .Select(x => int.Parse(Regex.Replace(x, @"M-(\d+)", "$1"))) + .OrderByDescending(x => x) + //.Select(x => $"M-{x}") + .First(); + //_ctfGlobalID.Dump(); + var part1 = (from msdrg in DimMSDRGs + where msdrg.DRGSchema == "2021MSDRG" + && !_2020MSDRGs.Contains(msdrg.MSDRGCode) + select new + { + msdrg.MSDRGCode, + CaseTypeFamilyName = ti.ToTitleCase(msdrg.Description.ToLower()) + }) + .ToList(); + var part2 = (from msdrg in DimMSDRGs + where msdrg.DRGSchema == "2021MSDRG" + && !_caseTypeFamilyMappingICD10.Contains(msdrg.MSDRGCode) + select new + { + msdrg.MSDRGCode, + CaseTypeFamilyName = ti.ToTitleCase(msdrg.Description.ToLower()) + }) + .ToList(); + var results = part1.Union(part2).ToList() + .ConvertAll(x => + { + _ctfGlobalID++; + return new + { + CaseTypeFamilyGlobalID = $"M-{_ctfGlobalID}", + x.MSDRGCode, + x.CaseTypeFamilyName + }; + }); + //results.Dump("results"); + var deleteCaseTypeFamily = results + .Aggregate("", (x, y) => $"{x}\r\nDELETE FROM dss.CaseTypeFamily WHERE Name = '{y.CaseTypeFamilyName}' AND CaseTypeFamilyGlobalID = '{y.CaseTypeFamilyGlobalID}'"); + var insertCaseTypeFamily = results + .Aggregate($"INSERT INTO dss.CaseTypeFamily ( CaseTypeFamilyGUID, Name, CaseTypeFamilyGlobalID )\r\nVALUES", + (x, y) => $"{x}\r\n('{Guid.NewGuid()}', '{y.CaseTypeFamilyName}', '{y.CaseTypeFamilyGlobalID}'),").TrimEnd(",".ToCharArray()); + var deleteICD10 = results + .Aggregate("", (x, y) => $@"{x} +DELETE FROM dss.CaseTypeFamilyMappingICD10 +WHERE EXISTS(SELECT 1 FROM dss.CaseTypeFamily ctf + WHERE ctf.CaseTypeFamilyGlobalID = '{y.CaseTypeFamilyGlobalID}' AND SkipICD = 1 AND ctf.CaseTypeFamilyID = CaseTypeFamilyMappingICD10.CaseTypeFamilyID) +AND CaseTypeFamilyMappingICD10.MSDRGCode = '{y.MSDRGCode}' AND CaseTypeFamilyVersionID = 2"); + var insertICD10 = results + .Aggregate($"INSERT INTO dss.CaseTypeFamilyMappingICD10 ( CaseTypeFamilyID, SkipICD, ICD10Code, MSDRGCode, CaseTypeFamilyVersionID )\r\nVALUES", + (x, y) => $"{x}\r\n((SELECT ctf.CaseTypeFamilyID from dss.CaseTypeFamily ctf where ctf.CaseTypeFamilyGlobalID = '{y.CaseTypeFamilyGlobalID}'), 1, '0', '{y.MSDRGCode}', 2),").TrimEnd(new[] { ',' }); + + var migration = + deleteCaseTypeFamily + "\r\nGO\r\n" + + insertCaseTypeFamily + "\r\nGO\r\n" + + deleteICD10 + "\r\nGO\r\n" + + insertICD10 + "\r\nGO\r\n"; + + migration.Dump(); +} + +// Define other methods and classes here \ No newline at end of file diff --git a/Kevin Sql Parsing.linq b/Kevin Sql Parsing.linq new file mode 100644 index 0000000..dba2138 --- /dev/null +++ b/Kevin Sql Parsing.linq @@ -0,0 +1,84 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var filePath = @"D:\Git\2020-01-15-13-20 B-24820 UV Case Type Setup CPT Codes.sql"; +var regex = new Regex(@"[\r\n\s]+"); +var regex2 = new Regex(@"^[^']+'(C?[\d]+).+O-([\d]{4}).+$"); +var info = File.ReadAllText(filePath) + .Split(';') + .Select(x => x.TrimStart(new[] { '\r', '\n' })) + .Where(x => x.StartsWith("INSERT INTO [dss].[CaseTypeFamilyMappingCPT]")).ToList() + .ConvertAll(x => + { + x = regex.Replace(x, " "); + var CPTCode = regex2.Replace(x, "$1"); + var GlobalId = regex2.Replace(x, "O-$2"); + return new { GlobalId, CPTCode }; + }) + .GroupBy(x => x.GlobalId, (g, d) => new + { + GlobalId = g, + CPTCodes = d.Select(c => c.CPTCode) + }) + .OrderBy(x => x.GlobalId); +//info.Dump(); +info +.Aggregate(@"DECLARE @CaseTypeFamilyID INT +", (a, b) => $@"{a}SELECT @CaseTypeFamilyID = [CaseTypeFamilyID] FROM [dss].[CaseTypeFamily] WHERE [CaseTypeFamilyGlobalID] = '{b.GlobalId}'; +INSERT INTO [dss].[CaseTypeFamilyMappingCPT] ([CaseTypeFamilyID], [CPTCode], [CaseTypeFamilyVersionID]) +VALUES{b.CPTCodes.Aggregate("", (c, d) => $@"{c} + (@CaseTypeFamilyID, '{d}', 1),").TrimEnd(',')}; + +") +.Dump(); \ No newline at end of file diff --git a/Kevin's Python queries reversed engineered.linq b/Kevin's Python queries reversed engineered.linq new file mode 100644 index 0000000..53b6369 --- /dev/null +++ b/Kevin's Python queries reversed engineered.linq @@ -0,0 +1,105 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var timeClasses = new[] { 1, 4 }; +var departments = new[] { 115355, 115372, 115373, 45950, 45953, 45955, 45959, 45960, 45967, 45968, 45973, 45974, 45975, 45976, 45977, 45979, 45980, 45982, 45985, 45998, 46030, 59278, 74820 }; +var payperiods = new[] { 3136, 3135, 3134, 3133, 3132, 3131 }; +var hours = from fact in FactPayrollSampledPayPeriods + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + join prodclass in DimProductiveClasses on paycode.ProductiveClassID equals prodclass.ProductiveClassID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where prodclass.Name == "Productive" + && timeClasses.Contains(fact.TimeClassID) + && departments.Contains(fact.DepartmentID) + && payperiods.Contains(fact.PayPeriodID) + group new { fact, department, payperiod } by new { department.DepartmentID, payperiod.PayPeriodID, fact.TimeClassID } into g + select new { g.Key.DepartmentID, g.Key.PayPeriodID, g.Key.TimeClassID, Units = g.Sum(f => f.fact.Hours), UnitType = "hours" }; + +var dollars = from fact in FactPayrollSampledPayPeriods + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where timeClasses.Contains(fact.TimeClassID) + && departments.Contains(fact.DepartmentID) + && payperiods.Contains(fact.PayPeriodID) + group new { fact, department, payperiod } by new { department.DepartmentID, payperiod.PayPeriodID, fact.TimeClassID } into g + select new { g.Key.DepartmentID, g.Key.PayPeriodID, g.Key.TimeClassID, Units = g.Sum(f => f.fact.Dollars), UnitType = "dollars" }; + +var uos = from fact in ViewPrimaryStatisticsStaffingByPayPeriod + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where timeClasses.Contains(fact.TimeClassID) + && departments.Contains(fact.DepartmentID) + && payperiods.Contains(fact.PayPeriodID) + group new { fact, department, payperiod } by new { department.DepartmentID, payperiod.PayPeriodID, fact.TimeClassID } into g + select new { g.Key.DepartmentID, g.Key.PayPeriodID, g.Key.TimeClassID, Units = g.Sum(f => f.fact.Units) ?? 0.0m, UnitType = "uos" }; + +hours.Concat(dollars).Concat(uos) +//.Where(x => departments.Contains(x.DepartmentID) && payperiods.Contains(x.PayPeriodID)) +.Join(DimDepartments, m => m.DepartmentID, d => d.DepartmentID, (m, d) => new { m.DepartmentID, m.PayPeriodID, m.TimeClassID, m.Units, m.UnitType, Department = d.Name }) +.Join(DimPayPeriods, m => m.PayPeriodID, p => p.PayPeriodID, (m, p) => new { m.DepartmentID, m.PayPeriodID, m.TimeClassID, m.Units, m.UnitType, m.Department, p.PeriodStartCalendarDate, p.PeriodEndCalendarDate }) +.Join(DimTimeClasses, m => m.TimeClassID, t => t.TimeClassID, (m, t) => new { m.DepartmentID, m.PayPeriodID, m.TimeClassID, m.Units, m.UnitType, m.Department, m.PeriodStartCalendarDate, m.PeriodEndCalendarDate, t.TimeClassCode, TimeClass = t.Name, t.SortOrder }) +.OrderBy(x => x.DepartmentID) +.ThenBy(x => x.PayPeriodID) +.ThenBy(x => x.UnitType) +.ThenBy(x => x.SortOrder) +.Dump(); \ No newline at end of file diff --git a/Localization DateTime Helpers.linq b/Localization DateTime Helpers.linq new file mode 100644 index 0000000..d9fbcf5 --- /dev/null +++ b/Localization DateTime Helpers.linq @@ -0,0 +1,76 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.Globalization + + +void Main() +{ + var culture = new CultureInfo("en-US"); + var databaseTime = new DateTime(1900,9,9,13,9,09, DateTimeKind.Utc); + GetUTCLocalDateTime(databaseTime).ToString(culture.DateTimeFormat.ShortDatePattern).Dump(); +} + +// Define other methods and classes here +/// +/// convert UTC time from the database to the machine's time +/// +/// +/// +internal DateTime GetUTCLocalDateTime(DateTime dateTime) +{ + var localTime = dateTime.ToLocalTime(); + + // convert local time to UTC for database save + var utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(localTime); + return localTime.ToUniversalTime().Subtract(utcOffset); +} diff --git a/MailGun Test with Template Data.linq b/MailGun Test with Template Data.linq new file mode 100644 index 0000000..495d4ad --- /dev/null +++ b/MailGun Test with Template Data.linq @@ -0,0 +1,175 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + RestSharp.Authenticators + + +private static string baseurl = "https://dev.sdt.local/StrataJazz201931"; +private static Random _rnd; + +void Main() +{ + var now = DateTime.Today.AddDays(-1 * (7 + ((DateTime.Today.DayOfWeek - DayOfWeek.Monday)) % 7)); + var staffing = new Staffing + { + pr = new PayPeriod + { + StartDate = now.AddDays(-14), + EndDate = now.AddDays(-7) + }, + Departments = Enumerable.Range(0, 26).ToList() + .ConvertAll(e => //new Department { department = + new DeptInfo($"dept_{e}", Random.Next() * 10m, Random.Next() * 10m, Random.Next() * 10m * Random.Next(-1, 1)) + //} + ) + }; + var data = JsonConvert.SerializeObject(staffing); + data.Dump(); + SendMessageByTemplateId(data).Content.Dump(); +} + +internal static Random Random +{ + get => _rnd ?? (_rnd = new Random()); + set => _rnd = value; +} + +// Define other methods and classes here +public class Staffing +{ + public PayPeriod pr { get; set; } + public List overall => new List { Departments.FirstOrDefault() }; + public List departments => new List + { + new DeptInfo( + $"Current Pay Period ({pr.endDate:M/dd})", + Departments.Sum(d => d.latest_total_variance), + Departments.Sum(d => d.latest_pay_variance), + Departments.Sum(d => d.latest_flex_variance) + ) + }; + internal List Departments { get; set; } +} + +public class PayPeriod +{ + internal DateTime StartDate { get; set; } + internal DateTime EndDate { get; set; } + public string startDate => StartDate.ToString("MM/dd"); + public string endDate => EndDate.ToString("MM/dd"); +} + +public class Department +{ + public DeptInfo department { get; set; } +} + +public class DeptInfo +{ + public string hyperlink => baseurl; + public string name { get; set; } + internal decimal latest_total_variance { get; set; } + internal decimal latest_pay_variance { get; set; } + internal decimal latest_flex_variance { get; set; } + public string total_variance => $"{latest_total_variance:C}"; + public string pay_variance => $"{latest_pay_variance:C}"; + public string flex_variance => $"{latest_flex_variance:C}"; + public string six_month_total_chart => "graph_sparkline_6_pay_period_-1281183930.png"; + public string six_month_pay_chart => "graph_sparkline_6_pay_period_1140344931.png"; + public string six_month_flex_chart => "graph_sparkline_6_pay_period_489356044.png"; + public string total_color => latest_total_variance >= 0 ? "positive" : "negative"; + public string pay_color => latest_pay_variance >= 0 ? "positive" : "negative"; + public string flex_color => latest_flex_variance >= 0 ? "positive" : "negative"; + + public DeptInfo(string deptName, decimal total, decimal pay, decimal flex) + { + name = deptName; + latest_total_variance = total; + latest_pay_variance = pay; + latest_flex_variance = flex; + } +} + +public static IRestResponse SendMessageByTemplateId(string jsonStr) +{ + RestClient client = new RestClient(); + client.BaseUrl = new Uri("https://api.mailgun.net/v3/notifications-dev.stratanetwork.com"); + client.Authenticator = + new HttpBasicAuthenticator("api", + "key-12ea6389d906cef290ad8a0557a3a8c4"); + RestRequest request = new RestRequest(); + //request.AddParameter("domain", "notifications.stratanetwork.com", ParameterType.UrlSegment); + //request.Resource = "{domain}/messages"; + request.Resource = "/messages"; + request.AddParameter("from", "Mailgun Sandbox "); + //request.AddParameter("to", "Dhara "); + //request.AddParameter("to", "Nicole "); + request.AddParameter("to", "Thom Lamb "); + //request.AddParameter("to", "Kevin Lamb "); + //request.AddParameter("to", "Shruthi Agni "); + //request.AddParameter("to", "Tucker Debolt "); + request.AddParameter("subject", "Hello Thom Lamb"); + //request.AddParameter("template", "daily_pr_snapshot"); + request.AddParameter("template", "overall_pr_notification"); + request.AddParameter("h:X-Mailgun-Variables", jsonStr); + request.Method = Method.POST; + return client.Execute(request); +} \ No newline at end of file diff --git a/MonthNames.linq b/MonthNames.linq new file mode 100644 index 0000000..09ee294 --- /dev/null +++ b/MonthNames.linq @@ -0,0 +1,68 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + TimeZoneNames + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.Globalization + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + TimeZoneNames + + +Enumerable.Range(1, 12).ToList() + .Select(mm => new { Key = mm, Value = CultureInfo.GetCultureInfo("hi-IN").DateTimeFormat.GetMonthName(mm) }) + .ToDictionary(item => item.Key, item => item.Value) + .Dump(); diff --git a/Move files to new name.linq b/Move files to new name.linq new file mode 100644 index 0000000..a7e31c5 --- /dev/null +++ b/Move files to new name.linq @@ -0,0 +1,95 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var dir = @"D:\Git\stratasphere.web.api.service"; +var files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories) + .Select(d => new + { + file = d, + dir = Path.GetDirectoryName(d), + oldFile = Path.GetFileName(d), + ext = Path.GetExtension(d) + }) + //.Where(d => !d.dir.Contains(".git")) + .Select(d => new + { + d.file, + d.dir, + d.oldFile, + d.ext, + newFile = d.oldFile.Contains("StrataSphere") ? d.oldFile.Replace("StrataSphere", "StarterSet") : "" + }) + .Where(d => !d.dir.Contains(".git") && !string.IsNullOrEmpty(d.newFile)) + .Select(d => new + { + d.file, + d.dir, + d.oldFile, + d.ext, + d.newFile, + moveTo = string.IsNullOrEmpty(d.newFile) ? "" : Path.Combine(d.dir, d.newFile) + }); +files.Dump(); +files.ToList() +.ForEach(f => +{ + var moveTo = Path.Combine(f.dir, f.newFile); + try + { + $"Directory.Move({f.file}, {moveTo});".Dump(); + Directory.Move(f.file, moveTo); + } + catch (Exception ex) + { } +}); \ No newline at end of file diff --git a/New StarterSet Cube Parameters.linq b/New StarterSet Cube Parameters.linq new file mode 100644 index 0000000..6b4b8d3 --- /dev/null +++ b/New StarterSet Cube Parameters.linq @@ -0,0 +1,79 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst StrataSphere 20191104.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var insert = (from rcrp in REDSCubeReportParameters +join sd in ScoreDimensions on rcrp.Name equals sd.FriendlyName +join sh in ScoreHierarchies on sd.DefaultHierarchyGUID equals sh.HierarchyGUID +select new {rcrp.Name, rcrp.DimensionID, rcrp.AttributeID, sd.DimensionGUID, HierarchyGUID = sd.DefaultHierarchyGUID, AttributeGUID = sd.DefaultLookupKeyGUID, sh.HierarchyID}) +.Distinct() +.ToList() +.Aggregate(@"INSERT INTO stratasphere.Definition +( Id, Name, Description, DateCreated, DateLastModified, AttributeGuid, DimensionGuid, AttributeId, DimensionId, HierarchyGuid, HierarchyId ) +SELECT Id, Name, Description, DateCreated, DateLastModified, AttributeGUID, DimensionGuid, AttributeID, DimensionId, HierarchyGuid, HierarchyId +FROM ( +VALUES +", (x, y) => $@"{x}(NEWID(),'{y.Name}','{y.Name}',SYSDATETIME(),SYSDATETIME(),'{y.AttributeGUID}','{y.DimensionGUID}','{y.AttributeID}','{y.DimensionID}','{y.HierarchyGUID}','{y.HierarchyID}'), +"); +insert += @") AS x (Id, Name, Description, DateCreated, DateLastModified, AttributeGUID, DimensionGuid, AttributeID, DimensionId, HierarchyGuid, HierarchyId) +WHERE NOT EXISTS (SELECT 1 FROM stratasphere.Definition d WHERE d.Name = x.Name +OR (d.DimensionId = x.DimensionId AND d.AttributeId = x.AttributeID) +OR (d.DimensionGUID = x.DimensionGUID AND d.AttributeGUID = x.AttributeGUID))"; +insert.Dump(); \ No newline at end of file diff --git a/Nursing Census Data Analysis.linq b/Nursing Census Data Analysis.linq new file mode 100644 index 0000000..d14973e --- /dev/null +++ b/Nursing Census Data Analysis.linq @@ -0,0 +1,161 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst CNE 20191210.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var configurationGuid = Guid.Parse("880C4912-5A58-40B7-ADB1-1F9BD365E6AF"); + (from sd in StaffingToDemandPatientVolumes + where new[] {21398, 21915}.Contains(sd.DepartmentID) + select sd).ToList() + .OrderBy(g => g.DepartmentID) + .ThenBy(g => g.IsBaseline) + .ThenBy(g => g.DayOfWeek) + .ThenBy(g => g.Seasonality) + .ThenBy(g => g.Hour) + + .Dump(nameof(StaffingToDemandPatientVolumes)); + var CensusData = + from obj in Nursings + join f in DimFunctionalAreas on obj.DimDepartment.FunctionalAreaID equals f.FunctionalAreaID + join fj in NursingFlexJobCodeGroups on obj.NursingGUID equals fj.NursingGUID + join j in DimFlexJobCodeGroups on fj.FlexJobCodeGroupID equals j.FlexJobCodeGroupID + where obj.ConfigurationGUID == configurationGuid + select new + { + obj.DepartmentID, + obj.NumOfBeds, + obj.IsComplete, + obj.IsNewborn, + InPatientDays = new FlattenDays("InPatientDays", obj).Values, + ObservationDays = new FlattenDays("ObservationDays", obj).Values, + NewbornInPatientDays = new FlattenDays("NewbornInPatientDays", obj).Values, + NewbornObservationDays = new FlattenDays("NewbornObservationDays", obj).Values, + Seasonality = new FlattenSeasonality("Seasonality", obj).Values, + obj.DimDepartment.Name, + FunctionalAreaName = f.Name, + fj.WHPPDBaseline, + fj.MedianAnnualWageBaseline, + fj.DirectCarePercentageBaseline, + fj.UnproductivePercentBaseline, + fj.WHPPD, + fj.MedianAnnualWage, + fj.DirectCarePercentage, + fj.UnproductivePercent, + fj.PatientCare, + fj.AcutyAdjustment, + fj.RoundingRule, + fj.FlexJobCodeGroupID, + fj.StaffingModelType, + StaffingModelConfig = Newtonsoft.Json.JsonConvert.DeserializeObject(fj.StaffingModelConfig),//.PatientRatios, + JobName = j.Name, + j.Code, + j.SortOrder + }; + CensusData.Where(cd => new [] {"2310 - 11150 - DELIVERY","2110 - 11071 - RIVERVIEW 3"}.Contains(cd.Name) && cd.JobName == "RN").Dump(); +} + +// Define other methods and classes here +public class ModelValue +{ + public IList ModelValues { get; set; } + internal Dictionary> PatientRatios => ModelValues + .GroupBy(mv => mv.DayOfWeek, (dayOfWeek, d) => new + { + dayOfWeek, + HourlyRatios = d.Select(x => new { x.HourOfDay, x.PatientRatio }) + .ToDictionary(key => key.HourOfDay, value => value.PatientRatio) + }).ToDictionary(key => key.dayOfWeek, value => value.HourlyRatios); +} + +public class StaffingModel +{ + public int DayOfWeek { get; set; } + public int HourOfDay { get; set; } + public double PatientRatio { get; set; } +} + +public class FlattenDays +{ + public IEnumerable Values { get; set; } + public FlattenDays(string name, Nursing obj) + { + var regex = new Regex($"Month[\\d]{{2}}{name}", RegexOptions.IgnoreCase); + Type t = typeof(Nursing); + var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance) + .Where(f => regex.IsMatch(f.Name)) + .OrderBy(f => f.Name); + Values = fields.Select(field => (double)field.GetValue(obj)); + } +} + +public class FlattenSeasonality +{ + public IEnumerable Values { get; set; } + public FlattenSeasonality(string name, Nursing obj) + { + var regex = new Regex($"Month[\\d]{{2}}{name}", RegexOptions.IgnoreCase); + Type t = typeof(Nursing); + var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance) + .Where(f => regex.IsMatch(f.Name)) + .OrderBy(f => f.Name); + Values = fields.Select(field => (byte)field.GetValue(obj)); + } +} \ No newline at end of file diff --git a/PayPeriod query.linq b/PayPeriod query.linq new file mode 100644 index 0000000..821d87e --- /dev/null +++ b/PayPeriod query.linq @@ -0,0 +1,81 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +(from fact in FactPayrollSampledPayPeriods + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + join prodclass in DimProductiveClasses on paycode.ProductiveClassID equals prodclass.ProductiveClassID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where prodclass.Name == "Productive" + && payperiod.PeriodEndCalendarDate < DateTime.Now + select new { fact.DepartmentID, fact.PayPeriodID, payperiod.PeriodEndCalendarDate, payperiod.PeriodStartCalendarDate }) + .GroupBy(r => r.DepartmentID, (key, grp) => + new + { + DepartmentID = key, + data = grp.Select(g => + new + { + g.PayPeriodID, + g.PeriodEndCalendarDate, + g.PeriodStartCalendarDate + }).Distinct().OrderByDescending(g => g.PeriodEndCalendarDate).Take(6) + }) \ No newline at end of file diff --git a/Pokemon API.linq b/Pokemon API.linq new file mode 100644 index 0000000..5c888d6 --- /dev/null +++ b/Pokemon API.linq @@ -0,0 +1,65 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + System.Dynamic + + +var client = new RestClient(); +client.BaseUrl = new Uri(@"http://pokeapi.co/api/v2/pokemon?limit=999"); +RestRequest request = new RestRequest(); +request.Method = Method.GET; +dynamic content = JsonConvert.DeserializeObject(client.Execute(request).Content); +((object)content).Dump(); +object name = MyExtensions.IsPropertyExist(content, "forms") ? content.forms[0].name : null; +if (name != null) name.Dump(); \ No newline at end of file diff --git a/Random Color Hex Value.linq b/Random Color Hex Value.linq new file mode 100644 index 0000000..4b5165c --- /dev/null +++ b/Random Color Hex Value.linq @@ -0,0 +1,57 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var rand = new Random(); +var color = $"#{(0x1000000 + (rand.Next()) * 0xffffff):X4}".Substring(0, 7); +color.Dump(); \ No newline at end of file diff --git a/ScoreDimensions.linq b/ScoreDimensions.linq new file mode 100644 index 0000000..f650c7a --- /dev/null +++ b/ScoreDimensions.linq @@ -0,0 +1,143 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst Grady 20191107.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var test = (from sd in ScoreDimensions + select new StarterSetAdHocScoreDimensionInfo + { + DimensionGUID = sd.DimensionGUID, + FriendlyName = sd.FriendlyName, + GlobalID = sd.GlobalID + }).ToList(); + test.OrderByDescending(t => t.MDXMemberName).Dump(); +} + +// Define other methods and classes here + +public class StarterSetAdHocScoreDimensionInfo +{ + public Guid DimensionGUID { get; set; } + public string FriendlyName { get; set; } + public string GlobalID { get; set; } + public string AttributeId { get; set; } + public string MDXMemberID { get; set; } + public bool IsRollup { get; set; } + internal Regex ServiceLineRegex = new Regex(@"^Service Line (\d)$", RegexOptions.IgnoreCase); + public bool ServiceLineRegexIsMatch => ServiceLineRegex.IsMatch(FriendlyName); + + public string MDXMemberName + { + get + { + try + { + return AnalysisServicesUtils.GetHierarchyMDXName("Patient Encounter", + ServiceLineRegex.IsMatch(FriendlyName) && IsRollup + ? $"{ServiceLineRegex.Replace(FriendlyName, "Service Line Rollup ${1}")}" + : $"{FriendlyName}{(IsRollup ? " Rollup" : "")}"); + } + catch (Exception) + { + return string.Empty; + } + } + } + + internal string Name => $"Patient Encounter - {FriendlyName}{(IsRollup ? " Rollup" : "")}"; + + internal StarterSetAdHocScoreDimensionInfo() + { + MDXMemberID = string.Empty; + IsRollup = false; + } + +} + +public class AnalysisServicesUtils +{ + public static string GetHierarchyMDXName(string aDimensionName, string aHierarchyName) + { + var s = "[{0}].[{1}]"; + + return String.Format(s, GetASFriendlyName(aDimensionName), GetASFriendlyName(aHierarchyName)); + } + + public static string GetASFriendlyName(string aStr, bool aTrim = true) + { + //Invalid characters --> . , ; ' ` : / \ * | ? " & % $ ! + = ( ) [ ] { } + //Take out white space + var returnStr = System.Text.RegularExpressions.Regex.Replace(aStr, @"[\.,;'`:/\\\*\|\?""&%\$!\+=\(\)\[\]{}]", ""); + + if (aTrim) returnStr = returnStr.Trim(); + + //Replace reserved name + if (returnStr.Equals("Name", StringComparison.OrdinalIgnoreCase)) returnStr = "Name_"; + if (returnStr.Equals("Measures", StringComparison.OrdinalIgnoreCase)) returnStr = "Measures_"; + if (returnStr.Equals("ID", StringComparison.OrdinalIgnoreCase)) returnStr = "ID_"; + if (returnStr.Equals("Key", StringComparison.OrdinalIgnoreCase)) returnStr = "Key_"; + return returnStr; + } + + + + +} diff --git a/Snapshot classes testing.linq b/Snapshot classes testing.linq new file mode 100644 index 0000000..f78a47b --- /dev/null +++ b/Snapshot classes testing.linq @@ -0,0 +1,194 @@ + + + 6a7da5d6-5345-4fd8-9ca6-ab567ac5f639 + true + D0014-SQL-01.sdt.local + jazz tst UNC 20190716.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var Departments = (from dept in DeptPayPeriodSummaries + select new DeptPayPeriodSummary(dept)) + .ToList() + .GroupBy(d => d.DepartmentID, (key, dx) => new { key, data = dx.OrderBy(d => d.PeriodEndDate).ToList() }) + .Where(d => d.data.Sum(x => x.TotalVariance) != 0.0d) + .Select(grp => new DeptInfo(grp.data)); + Departments.Dump("Raw List"); + var top5 = Departments + .OrderBy(d => d.latest_total_variance) + .ThenBy(d => d.latest_pay_variance) + .ThenBy(d => d.latest_flex_variance) + .Take(5).ToList(); + var bottom5 = Departments + .OrderByDescending(d => d.latest_total_variance) + .ThenByDescending(d => d.latest_pay_variance) + .ThenByDescending(d => d.latest_flex_variance) + .Take(5).ToList(); + bottom5.Dump("Bottom5"); + top5.Dump("top5"); + var departments = (top5.Union(bottom5).Distinct()) + .OrderBy(d => d.latest_total_variance).ToList(); + departments.Dump("departments"); +} + +// Define other methods and classes here +public partial class DeptPayPeriodSummary +{ + public int DepartmentID { get; set; } + public int PayPeriodID { get; set; } + public string Department { get; set; } + public DateTime PeriodStartDate { get; set; } + public DateTime PeriodEndDate { get; set; } + public double ActualHours { get; set; } + public double ActualDollars { get; set; } + public double ActualUOS { get; set; } + public double TargetHours { get; set; } + public double TargetDollars { get; set; } + public double TargetUOS { get; set; } + public double VarianceHours { get; set; } + public double VarianceDollars { get; set; } + public double VarianceUOS { get; set; } + public double ActualPayRate => MathExtensions.DivideBy((double)ActualDollars, ActualHours); + public double TargetPayRate => MathExtensions.DivideBy((double)TargetDollars, TargetHours); + public double VariancePayRate => TargetPayRate - ActualPayRate; + public double PayRateVariance => VariancePayRate * ActualHours; + public double FlexVariance => VarianceHours * TargetPayRate; + public double TotalVariance => PayRateVariance + FlexVariance; + public double VariancePayDollars => (ActualPayRate - TargetPayRate) * ActualHours; + public double VarianceFlexDollars => TargetPayRate * VarianceHours; + + public DeptPayPeriodSummary(LINQPad.User.DeptPayPeriodSummary dept) + { + DepartmentID = dept.DepartmentID; + PayPeriodID = dept.PayPeriodID; + Department = dept.Department; + PeriodStartDate = dept.PeriodStartDate; + PeriodEndDate = dept.PeriodEndDate; + ActualHours = dept.ActualHours; + ActualDollars = dept.ActualDollars; + ActualUOS = dept.ActualUOS; + TargetHours = dept.TargetHours; + TargetDollars = dept.TargetDollars; + TargetUOS = dept.TargetUOS; + VarianceHours = dept.VarianceHours; + VarianceDollars = dept.VarianceDollars; + VarianceUOS = dept.VarianceUOS; + } + +} + +public class DeptInfo +{ + public string hyperlink => ""; + + internal int deptid { get; set; } + public string name { get; set; } + internal double latest_total_variance { get; set; } + internal double latest_pay_variance { get; set; } + internal double latest_flex_variance { get; set; } + public string total_variance => $"{latest_total_variance:C}"; + public string pay_variance => $"{latest_pay_variance:C}"; + public string flex_variance => $"{latest_flex_variance:C}"; + public string six_period_total_chart { get; set; } + public string six_period_pay_chart { get; set; } + public string six_period_flex_chart { get; set; } + public IEnumerable totalGraph { get; set; } + public IEnumerable payGraph { get; set; } + public IEnumerable flexGraph { get; set; } + public int graphMin { get; set; } + public int graphMax { get; set; } + public string total_color => latest_total_variance >= 0 ? "positive" : "negative"; + public string pay_color => latest_pay_variance >= 0 ? "positive" : "negative"; + public string flex_color => latest_flex_variance >= 0 ? "positive" : "negative"; + + public DeptInfo(List department) + { + deptid = department.First().DepartmentID; + name = department.First().Department; + latest_total_variance = department.Sum(d => d.TotalVariance); + latest_pay_variance = department.Sum(d => d.PayRateVariance); + latest_flex_variance = department.Sum(d => d.FlexVariance); + totalGraph = department.Select(d => Convert.ToInt32(d.TotalVariance)); + payGraph = department.Select(d => Convert.ToInt32(d.PayRateVariance)); + flexGraph = department.Select(d => Convert.ToInt32(d.FlexVariance)); + graphMin = Math.Min(Math.Min(totalGraph.Min(), payGraph.Min()), flexGraph.Min()); + graphMax = Math.Max(Math.Max(totalGraph.Max(), payGraph.Max()), flexGraph.Max()); + } + + public DeptInfo(int departmentId, string deptName, double total, double pay, double flex) + { + deptid = departmentId; + name = deptName; + latest_total_variance = total; + latest_pay_variance = pay; + latest_flex_variance = flex; + } + + internal string GetLinkUrlPath() => $"/PR/DepartmentProductivity.aspx?deptid={deptid}&mode=payperiod"; + + public bool Equals(DeptInfo x, DeptInfo y) + { + if (object.ReferenceEquals(x, y)) return true; + if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null)) return false; + return (x.deptid == y.deptid); + } + + public int GetHashCode(DeptInfo obj) + { + return obj.GetHashCode(); + } +} \ No newline at end of file diff --git a/Sole Hope/Sole Hope Inventory Complex.linq b/Sole Hope/Sole Hope Inventory Complex.linq new file mode 100644 index 0000000..988e55f --- /dev/null +++ b/Sole Hope/Sole Hope Inventory Complex.linq @@ -0,0 +1,305 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + <RuntimeDirectory>\System.Data.Entity.Design.dll + <RuntimeDirectory>\System.Data.Entity.dll + LINQtoCSV + LINQtoCSV + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.Globalization + System.IO.Compression + System.Data.Entity.Design.PluralizationServices + + +private PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + +void Main() +{ + var testExpando = new List(); + var meds = new List(); + var inputFileDescription = new CsvFileDescription + { + SeparatorChar = '\t', // tab delimited + FirstLineHasColumnNames = false, // no column names in first record + FileCultureName = "en-US" // use formats used in The Netherlands + }; + var cc = new CsvContext(); + var path = @"C:\Users\tlamb\Downloads\"; + var files = new[] { + @"Outreach - Monthly Inventory Records - Inventory - March.tsv", + @"Outreach - Monthly Inventory Records - Inventory - April.tsv", + @"Outreach - Monthly Inventory Records - Inventory - May.tsv", + @"Outreach - Monthly Inventory Records - Inventory - June.tsv" + }.ToList(); + var nextmonth = new DateTime(2019, 2, 1); + files.ForEach(inventory => + { + nextmonth = nextmonth.AddMonths(1); + var monthData = cc.Read(Path.Combine(path, inventory), inputFileDescription); + var data = ConvertToDataRow(ConvertMyDataRow(monthData, nextmonth).ToList()).ToList(); + meds.AddRange(data); + }); + + var medBrands = meds + .Select(m => new PropDef(m)) + .Distinct(new NameBrandComparer()) + .OrderBy(m => m.name).ThenBy(m => m.type) + .Select((m, i) => new + { + Id = i + 1, + Medication = m.name, + Brand = m.type, + Minimum = Math.Max(m.inventory.StartQty, 10), + m.inventory.Dosage, + Unit = m.inventory.container, //ps.Singularize(m.inventory.container.Trim("() ".ToCharArray())), + Package = Regex.Replace(m.inventory.PerBox, @"[^\d]*", ""), + Per = m.inventory.Per, //ps.Singularize(m.inventory.Unit.Trim("() ".ToCharArray())), + Purchased = m.inventory.Purchased + }) + .ToList(); + + medBrands.Dump(); + foreach (var m in meds) + { + var mbx = medBrands.FirstOrDefault(mb => m.Medicine.Trim() == mb.Medication && m.MedicineBrand.Trim() == mb.Brand); + if (mbx != null) + { + m.MedicineID = mbx.Id; + } + else + { + m.Dump(); + } + }; + meds.GroupBy(m => m.MedicineID) + .Select(grp => grp.Last()) + .OrderBy(m => m.MedicineID) + .ThenBy(m => m.Expiry) + .ThenBy(m => m.InvDate) + .Dump(); +} + +// Define other methods and classes here +internal IEnumerable ConvertMyDataRow(IEnumerable data, DateTime month) +{ + var groupData = data.SelectMany(dr => dr.ToList()) + .GroupBy(t => t.LineNbr) + .Select(t => new { Key = t.Key - 2, Values = t.ToList().Select(v => v.Value).ToArray() }); + //groupData.Dump("groupData"); + var properties = groupData.Where(d => d.Key < 0) + .SelectMany(d => d.Values.Select(v => Regex.Replace(v, @"[\s()]", "") + //.Replace("LastMonthsFinalQuantity", "Start_Quantity") + .Replace("StartingQuantityBeginningofMonth", "StartQuantity") + .Replace("StartingQuantityBeginningofCurrentMonth", "StartQuantity") + .Replace("FinalQuantityEndofMonth", "FinalQuantity") + .Replace("FinalQuantityEndofCurrentMonth", "FinalQuantity") + .Replace("MedicationTotalStartQuantity", "MedicationTotal")).ToList()).ToArray(); + //properties.Dump("properties"); + var medication = string.Empty; + var expandoData = groupData.Where(d => d.Key >= 0) + .Select((t, j) => + { + dynamic expando = new ExpandoObject(); + AddProperty(expando, "MedicineID", j); + AddProperty(expando, "InvDate", month); + int i = 0; + t.Values.ToList().ForEach(d => + { + var property = properties[i] + .Replace("Medication", "Medicine"); + if (property == "Medicine") + { + if (string.IsNullOrEmpty(d)) + { + d = medication; + } + medication = d; + } + AddProperty(expando, property, d ?? string.Empty); + i++; + }); + return expando; + }); + return expandoData; +} + +internal IEnumerable ConvertToDataRow(List data) +{ + var newData = + data.Select(d => (d as IDictionary)) + .Select(d => + { + var dr = new Inventory(); + d.Keys.ToList().ForEach(k => + { + var value = d[k]; + var name = Regex.Replace(k, "[^A-Za-z]", ""); + PropertyInfo prop = dr.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + if (null != prop && prop.CanWrite) + { + prop.SetValue(dr, value, null); + } + }); + return dr; + }); + return newData; +} + +// Define other methods and classes here +internal class MyDataRow : List, IDataRow +{ +} + +public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue) +{ + // ExpandoObject supports IDictionary so we can extend it like this + var expandoDict = expando as IDictionary; + if (expandoDict.ContainsKey(propertyName)) + expandoDict[propertyName] = propertyValue; + else + expandoDict.Add(propertyName, propertyValue); +} + +public class Inventory +{ + internal Regex regex = new Regex(@"\(?(Tube|Bottle|Tablet|Capsule|Lancet|Vial|Kit)[ s]?\)?", RegexOptions.IgnoreCase); + internal string PerBox { get; set; } + internal string container => ps.Singularize(regex.Match(PerBox).Value.Trim("() ".ToCharArray())); + internal string StartQuantity { get; set; } + internal string Received { get; set; } + internal string Output { get; set; } + internal string FinalQuantity { get; set; } + internal string Notes { get; set; } + internal string ExpirationDate { get; set; } + internal string LastMonthsFinalQuantity { get; set; } + + internal PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + + public int MedicineID { get; set; } + public DateTime InvDate { get; set; } + public string Medicine { get; set; } + public string MedicineBrand { get; set; } + public string Dosage { get; set; } + public string Unit { get; set; } + public string Pkg => container != string.Empty ? PerBox.Replace(container, "").TrimEnd() : PerBox; + public string Per => ps.Singularize((string.IsNullOrEmpty(container) ? regex.Match(Unit).Value : container).Trim()); + public int StartQty => ParseStartQuantity(StartQuantity, LastMonthsFinalQuantity); + public int FinalQty => ParseFinalQuantity(FinalQuantity); + public DateTime Purchased => !Notes.StartsWith("Purchased") ? new DateTime(2018,1,1).Date + : DateTime.Parse(Regex.Replace(Notes, @"[^\d/]*", "")); + public DateTime Expiry => ParseExpiry(); + public string Note => !Notes.StartsWith("Purchased") ? Notes : string.Empty; + // public string Medication { get; set; } + internal string BrandTotal { get; set; } + internal string MedicationTotal { get; set; } + + public Inventory() + { + Medicine = string.Empty; + Dosage = string.Empty; + PerBox = string.Empty; + StartQuantity = string.Empty; + Received = string.Empty; + Output = string.Empty; + FinalQuantity = string.Empty; + ExpirationDate = string.Empty; + Notes = string.Empty; + //Medication = string.Empty; + MedicineBrand = string.Empty; + BrandTotal = string.Empty; + MedicationTotal = string.Empty; + Unit = string.Empty; + LastMonthsFinalQuantity = string.Empty; + } + + internal DateTime ParseExpiry() + { + if (string.IsNullOrEmpty(ExpirationDate)) return DateTime.MaxValue.Date; + DateTime dt; + if (!DateTime.TryParseExact(ExpirationDate, @"M/yy", null, DateTimeStyles.None, out dt)) return DateTime.MaxValue.Date; + return dt; + } + + internal Int32 ParseFinalQuantity(string FinalQuantity) + { + var result = 0; + var regex = new Regex(@"[^\d]+", RegexOptions.IgnoreCase); + try + { + result = Convert.ToInt32("0" + (string.IsNullOrEmpty(FinalQuantity) || string.IsNullOrEmpty(regex.Replace(FinalQuantity, "")) + ? "" : regex.Replace(FinalQuantity, ""))); + } + catch (Exception ex) + { + ex.Message.Dump(); + } + return result; + } + + internal Int32 ParseStartQuantity(string StartQuantity, string LastMonthsFinalQuantity) + { + var result = 0; + var regex = new Regex(@"[^\d]+", RegexOptions.IgnoreCase); + try + { + result = Convert.ToInt32("0" + (!string.IsNullOrEmpty(regex.Replace(StartQuantity, "")) + ? regex.Replace(StartQuantity, "") + : !string.IsNullOrEmpty(regex.Replace(LastMonthsFinalQuantity, "")) + ? regex.Replace(LastMonthsFinalQuantity, "") : "")); + } + catch (Exception ex) + { + ex.Message.Dump(); + } + return result; + } +} + +public class PropDef +{ + public string name { get; set; } + public string type { get; set; } + public Inventory inventory { get; set; } + + public PropDef(string a, System.Type b) + { + name = a; + type = b.Name; + } + public PropDef(Inventory inv) + { + name = inv.Medicine == string.Empty ? inv.MedicineBrand.Trim() : inv.Medicine.Trim(); + type = inv.Medicine == string.Empty ? string.Empty : inv.MedicineBrand.Trim(); + inventory = inv; + } +} + +public class NameBrandComparer : IEqualityComparer +{ + public bool Equals(PropDef med1, PropDef med2) + { + if (med1 == null && med2 == null) return true; + else if (med1 == null || med2 == null) return false; + else if (med1.inventory != null && med2.inventory != null) + { + if (med1.name == med2.name && med1.type == med2.type && med1.inventory.Purchased == med2.inventory.Purchased) return true; + else return false; + } + else if (med1.name == med2.name && med1.type == med2.type) return true; + else + return false; + } + + public int GetHashCode(PropDef med) + { + return $"{med.name}{med.type}".GetHashCode(); + } +} + diff --git a/Sole Hope/Sole Hope Inventory Normalized.linq b/Sole Hope/Sole Hope Inventory Normalized.linq new file mode 100644 index 0000000..9492863 --- /dev/null +++ b/Sole Hope/Sole Hope Inventory Normalized.linq @@ -0,0 +1,237 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + AutoMapper + AutoMapper + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + AutoMapper.Configuration.Annotations + static UserQuery + + +private IDResolver idResolver = new IDResolver(); + +protected MapperConfiguration config { get; } = new MapperConfiguration(cfg => +{ + cfg.AddMaps(Assembly.GetExecutingAssembly()); + cfg.Advanced.AllowAdditiveTypeMapCreation = true; + cfg.ValidateInlineMaps = false; +}); + +void Main() +{ + + NameBrandExpiryComparer nameBrandExpiryEqC = new NameBrandExpiryComparer(); + NameBrandComparer nameBrandEqC = new NameBrandComparer(); + + Mapper.Reset(); + IMapper mapper = new Mapper(config); + mapper.ConfigurationProvider.CompileMappings(); + mapper.ConfigurationProvider.AssertConfigurationIsValid(); + + var path = @"C:\Users\Tlamb\Downloads"; + var json = "medications.json"; + var data = LoadFile(Path.Combine(path, json)); + + var meds = mapper.Map>(data.records); + var medBrandList = meds.Distinct(nameBrandEqC) + .OrderBy(m => m.Name).ThenBy(m => m.Brand) + .Select((m, i) => mapper.Map(m, opt => opt.Items["id"] = i)) + .ToList(); + medBrandList.Dump("MedBrands"); + + var withLabels = medBrandList.Select(m => mapper.Map(m, opt => opt.Items["id"] = m.MedicineID)); //new MedBrandLabel(m)); + withLabels.Dump("MedBrands with Labels"); + + var medList = meds.Distinct(nameBrandExpiryEqC) + .Join(medBrandList + , exp => new { exp.Name, exp.Brand } + , key => new { key.Name, key.Brand }, + (exp, key) => new MedInventory + { + MedicineID = key.MedicineID, + Start = exp.Start, + Expiry = exp.Expiry, + }) + .OrderBy(m => m.MedicineID).ThenBy(m => m.Expiry) + .ToList(); + medList.Dump("Med List"); + var medInv = medList.Select(ml => mapper.Map(ml, opt => opt.Items["medBrands"] = withLabels.ToDictionary(key => key.MedicineID, label => label.Label))); + medInv.Dump("Med Inventory"); + + meds.OrderBy(m => m.Name).ThenBy(m => m.Brand).ThenBy(m => m.Expiry).Dump(); + +} + +public RootObject LoadFile(string fileName) +{ + var jsonFile = File.ReadAllText(fileName); + return JsonConvert.DeserializeObject(jsonFile); +} + +// Define other methods and classes here + +public class NameBrandExpiryComparer : IEqualityComparer +{ + public bool Equals(Medication med1, Medication med2) + { + if (med1 == null && med2 == null) return true; + else if (med1 == null || med2 == null) return false; + else if (med1.Name == med2.Name && med1.Brand == med2.Brand && med1.Expiry == med2.Expiry) return true; + else + return false; + } + + public int GetHashCode(Medication med) + { + return $"{med.Name}{med.Brand}{med.Expiry:MMddyyyy}".GetHashCode(); + } +} + +public class NameBrandComparer : IEqualityComparer +{ + public bool Equals(Medication med1, Medication med2) + { + if (med1 == null && med2 == null) return true; + else if (med1 == null || med2 == null) return false; + else if (med1.Name == med2.Name && med1.Brand == med2.Brand) return true; + else + return false; + } + + public int GetHashCode(Medication med) + { + return $"{med.Name}{med.Brand}".GetHashCode(); + } +} + +[AutoMap(typeof(Record))] +public class Medication +{ + [SourceMember(nameof(Record.field_48_raw))] + public int MedicineID { get; set; } + [SourceMember(nameof(Record.field_49_raw))] + public string Name { get; set; } + [SourceMember(nameof(Record.field_50_raw))] + public string Brand { get; set; } + [SourceMember(nameof(Record.field_51_raw))] + public int Start { get; set; } + [SourceMember(nameof(Record.field_55_raw))] + public int Minimum { get; set; } + [SourceMember(nameof(Record.field_57_raw))] + public Field57Raw field57 { get; set; } + public DateTime Expiry => field57?.iso_timestamp ?? DateTime.MaxValue; + [Ignore] + public bool NeedsReorder => (Start < Minimum) || (Expiry <= DateTime.Now); +} + +[AutoMap(typeof(Medication))] +public class MedBrand +{ + [ValueResolver(typeof(IDResolver))] + public int MedicineID { get; set; } + public string Name { get; set; } + public string Brand { get; set; } + public int Minimum { get; set; } + [Ignore] + public string Dosage { get; set; } + [Ignore] + public int Package { get; set; } + [Ignore] + public string Per { get; set; } + [Ignore] + public string Unit { get; set; } + + public MedBrand() + { + Minimum = 10; + Dosage = "50mg"; + Unit = "Tablet"; + Package = 250; + Per = "Bottle"; + } + +} + +[AutoMap(typeof(MedBrand))] +public class MedBrandLabel : MedBrand +{ + [Ignore] + public string Label => $"{Name} {Brand} {Dosage} {Package} {Per} / {Unit}"; +} + +public class MedInventory +{ + public int MedicineID { get; set; } + public int Start { get; set; } + public DateTime Expiry { get; set; } + public bool NeedsReorder => Expiry <= DateTime.Now; +} + +[AutoMap(typeof(MedInventory))] +public class MedInvLabel : MedInventory +{ + [ValueResolver(typeof(BrandResolver))] + public string MedicationBrand { get; set; } + [Ignore] + public string Label => $"{MedicationBrand} {Expiry:MM/dd/yyyy}"; +} + +public class Field57Raw +{ + public string date { get; set; } + public string date_formatted { get; set; } + public string hours { get; set; } + public string minutes { get; set; } + public string am_pm { get; set; } + public object unix_timestamp { get; set; } + public DateTime iso_timestamp { get; set; } + public string timestamp { get; set; } + public int time { get; set; } +} + +public class Record +{ + public string id { get; set; } + public int field_48_raw { get; set; } + public string field_49_raw { get; set; } + public string field_50_raw { get; set; } + public int field_51_raw { get; set; } + public int field_52_raw { get; set; } + public int field_53_raw { get; set; } + public int field_54_raw { get; set; } + public int field_55_raw { get; set; } + public bool field_56_raw { get; set; } + public Field57Raw field_57_raw { get; set; } + public string field_58_raw { get; set; } + public string field_63_raw { get; set; } +} + +public class RootObject +{ + public List records { get; set; } +} + +public class IDResolver : IValueResolver +{ + public int Resolve(object source, object destination, int id, ResolutionContext context) + { + id = (int)context.Items["id"]; + return id; + } +} + +public class BrandResolver : IValueResolver +{ + public string Resolve(MedInventory source, object destination, string label, ResolutionContext context) + { + label = ((Dictionary)context.Items["medBrands"])[source.MedicineID]; + return label; + } +} \ No newline at end of file diff --git a/Sole Hope/SoleHope Inventory refactoring.linq b/Sole Hope/SoleHope Inventory refactoring.linq new file mode 100644 index 0000000..c5ef252 --- /dev/null +++ b/Sole Hope/SoleHope Inventory refactoring.linq @@ -0,0 +1,275 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + <RuntimeDirectory>\System.Data.Entity.Design.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + LINQtoCSV + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + LINQPad.Extensibility.DataContext.DbSchema + LINQtoCSV + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Globalization + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.Data.Entity.Design.PluralizationServices + + +private static PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + +void Main() +{ + var path = @"C:\Users\tlamb\downloads"; + var newPath = @"C:\Users\tlamb\downloads\Solehope 190705"; + var file = "medical inventory July 5 2019.2.csv"; + var filepath = Path.Combine(path, file); + + CsvFileDescription inputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', + FirstLineHasColumnNames = true, + IgnoreUnknownColumns = true + }; + + CsvFileDescription outputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', + FirstLineHasColumnNames = true + }; + + CsvContext cc = new CsvContext(); + IEnumerable medications; + IEnumerable inventory; + IEnumerable intake; + + var meds = cc.Read(filepath, inputFileDescription).ToList(); + meds.Dump(file); + + medications = meds.ConvertAll(med => (MedicationOut)med); + inventory = meds.ConvertAll(med => (Inventory)med); + inventory = inventory.OrderBy(i => i.Medication) + .Select((i, idx) => { i.InventoryId = idx.ToString(); return i; }); + intake = meds.ConvertAll(med => (Intake)med); + intake = intake + .Join(inventory, x => x.MedicationId, inv => inv.MedicationId, (x, inv) => new { intake = x, inv }).ToList() + .ConvertAll(u => { u.intake.InventoryId = u.inv.InventoryId; return u.intake; }); + + var updates = cc.Read(Path.Combine(@"C:\Users\tlamb\downloads\Solehope 190819", "intake2.csv"), inputFileDescription).ToList() + .Join(inventory, x => x.InventoryId, inv => inv.InventoryId, (x, inv) => new { intake = x, inv }).ToList() + .ConvertAll(u => { u.intake.MedicationId = u.inv.MedicationId; return u.intake; }); + + newPath.Dump("New Path"); + medications.Dump("Medications"); + inventory.Dump("Inventory"); + intake.Dump("Intake - from Medications"); + updates.Dump("Updates"); + + file = "medication.csv"; + filepath = Path.Combine(newPath, file); + cc.Write(medications, filepath, outputFileDescription); + file = "inventory.csv"; + filepath = Path.Combine(newPath, file); + cc.Write(inventory, filepath, outputFileDescription); + file = "intake.csv"; + filepath = Path.Combine(newPath, file); + cc.Write(intake, filepath, outputFileDescription); + file = "updates.csv"; + filepath = Path.Combine(newPath, file); + cc.Write(updates, filepath, outputFileDescription); +} + +// Define other methods and classes here + +public class Med +{ + public string Id { get; set; } + + public string Type { get; set; } + + [CsvColumn(Name = "Medication")] + public string MedicationStr { get; set; } + internal string Medications => box.Match(MedicationStr.Trim()).Success ? box.Replace(MedicationStr.Trim(), "$1").Trim() : MedicationStr.Trim(); + + public string Strength { get; set; } + + [CsvColumn(Name = "Quantity")] + public string Start { get; set; } + internal int StartCnt => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(Start) ? "0" : Start, "")); + + [CsvColumn(Name = "Minimum")] + public string MinimumStr { get; set; } + internal int MinimumCnt => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(MinimumStr) ? "0" : MinimumStr, "")); + + public string Unit { get; set; } + + public string Package { get; set; } + + [CsvColumn(Name = "Number")] + public string NumberStr { get; set; } + internal int NumberCnt => box.Match(MedicationStr.Trim()).Success ? Convert.ToInt32(box.Replace(MedicationStr.Trim(), "$2")) + : Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(NumberStr) ? "0" : NumberStr, "")); + + [CsvColumn(Name = "Expiration Date")] + public string Expiry { get; set; } + internal DateTime ExpiryDate => GetDateFromString(Expiry); + + internal string Form => string.IsNullOrEmpty(Package) ? "" + : Package.Trim() == "Tube/Cream" ? "Cream" : ps.Singularize(Package.Trim()); + internal string UnitOut => !string.IsNullOrEmpty(UnitNoBox) + ? ps.Singularize(UnitNoBox) + : string.IsNullOrEmpty(Package) + ? string.Empty + : Package.Trim() == "Tube/Cream" + ? "Tube" + : string.Empty; + + public string Label => $"{Medications} {Strength} {Form} {NumberCnt} / {UnitOut}"; + + internal string UnitNoBox => box.Match(MedicationStr.Trim()).Success ? "Box" : Unit?.Trim() ?? ""; + + internal Regex regex = new Regex(@"[^\d]"); + internal Regex date = new Regex(@"([\d]{1,2})/([\d]{1,2})/([\d]{1,4})"); + internal Regex shortDate = new Regex(@"([\d]{1,2})/([\d]{1,2})"); + internal Regex box = new Regex(@"^(\D*)([\d]*)/Box$"); + + internal DateTime GetDateFromString(string theDate) + { + DateTime result = DateTime.MaxValue; + DateTime work; + if (string.IsNullOrEmpty(theDate) || theDate == "0/0") + work = result; + else if (date.IsMatch(theDate)) + work = Convert.ToDateTime(theDate); + else if (shortDate.IsMatch(theDate)) + work = Convert.ToDateTime(shortDate.Replace(theDate, "$1/5/$2")); + else + work = result; + work = new DateTime(work.Year, work.Month, DateTime.DaysInMonth(work.Year, work.Month)); + return work; + } + +} + +public class MedicationOut +{ + public string Id { get; set; } + public string Type { get; set; } + public string Medication { get; set; } + public int Minimum { get; set; } + public string Strength { get; set; } + public string Form { get; set; } + public int Number { get; set; } + public string Unit { get; set; } + public string Label { get; internal set; } + + public static explicit operator MedicationOut(Med med) + { + return new MedicationOut + { + Id = med.Id, + Type = med.Type, + Medication = med.Medications, + Minimum = med.MinimumCnt, + Strength = med.Strength ?? "", + Form = med.Form, + Number = med.NumberCnt, + Unit = !string.IsNullOrEmpty(med.UnitNoBox) + ? ps.Singularize(med.UnitNoBox) + : string.IsNullOrEmpty(med.Package) + ? string.Empty + : med.Package.Trim() == "Tube/Cream" + ? "Tube" + : string.Empty, + Label = med.Label + }; + } +} + +public class Inventory +{ + public string MedicationId { get; set; } + public string InventoryId { get; set; } + public string Medication { get; set; } + public int Start => 0; + public string Label { get; internal set; } + public string Note { get; set; } + + public static explicit operator Inventory(Med med) + { + return new Inventory + { + MedicationId = med.Id, + Medication = med.Medications, + Label = med.Label, + Note = string.Empty + }; + } +} + +public class Intake +{ + public string MedicationId { get; set; } + public string InventoryId { get; set; } + public string Medication { get; set; } + public int Received { get; set; } + public DateTime Date { get; set; } + public DateTime Expiry { get; set; } + internal string MedLabel { get; set; } + public string Label => $"({Received}) {MedLabel}"; + + public static explicit operator Intake(Med med) + { + return new Intake + { + MedicationId = med.Id, + Medication = med.Medications, + Received = med.StartCnt, + Date = new DateTime(2019, 7, 5), + Expiry = med.ExpiryDate, + MedLabel = med.Label + }; + } +} \ No newline at end of file diff --git a/Sole Hope/SoleHopeInventory.linq b/Sole Hope/SoleHopeInventory.linq new file mode 100644 index 0000000..1a34062 --- /dev/null +++ b/Sole Hope/SoleHopeInventory.linq @@ -0,0 +1,536 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + <RuntimeDirectory>\System.Data.Entity.Design.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + LINQtoCSV + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + LINQtoCSV + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.Data.Entity.Design.PluralizationServices + System.Globalization + + +void Main() +{ + IEnumerable testExpando; + var inputFileDescription = new CsvFileDescription + { + SeparatorChar = '\t', // tab delimited + FirstLineHasColumnNames = false, // no column names in first record + FileCultureName = "en-US" // use formats used in The Netherlands + }; + var outputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', // tab delimited + FirstLineHasColumnNames = true, // no column names in first record + EnforceCsvColumnAttribute = true, + FileCultureName = "en-US" // use formats used in The Netherlands + }; + var cc = new CsvContext(); + var path = @"C:\Users\tlamb\Downloads\"; + var files = new[] { + @"Outreach - Monthly Inventory Records - Inventory March.tsv", + @"Outreach - Monthly Inventory Records - Inventory - April.tsv", + @"Outreach - Monthly Inventory Records - Inventory - May.tsv", + @"Outreach - Monthly Inventory Records - Inventory - June.tsv" + }.ToList(); + var nextmonth = new DateTime(2019, 2, 1); + var productList = new List(); + var purchaseSummary = new List(); + var orderSummary = new List(); + files.ForEach(inventory => + { + nextmonth = nextmonth.AddMonths(1); + var monthData = cc.Read(Path.Combine(path, inventory), inputFileDescription); + testExpando = ConvertMyDataRow(monthData); + var products = testExpando.Select(o => new Product(o as ExpandoObject, nextmonth)).ToList(); + var purchases = testExpando.Select(o => new Purchase(o as ExpandoObject, nextmonth)).Where(p => p.Rcvd != 0).ToList(); + var orders = testExpando.Select(o => new Order(o as ExpandoObject, nextmonth)).Where(o => o.Out != 0).ToList(); + productList.AddRange(products); + purchaseSummary.AddRange(purchases); + orderSummary.AddRange(orders); + }); + var medicationBrandList = productList.GroupBy(l => new { l.Medicine, l.Brand }).Select(grp => grp.First()).ToList() + .Select(mb => new MedicationBrand { Medicine = mb.Medicine, Brand = mb.Brand, Reorder = mb.MinimumRequired }); + productList.GroupBy(p => p.Medicine).OrderBy(p => p.Key).Dump("Products"); + purchaseSummary.Dump("Purchases"); + orderSummary.Dump("Orders"); + medicationBrandList.Dump("Medications"); + var docsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "SoleHope"); + if (!Directory.Exists(docsFolder)) + Directory.CreateDirectory(docsFolder); + cc.Write(medicationBrandList, Path.Combine(docsFolder, "MedicationBrand.csv"), outputFileDescription); + cc.Write(productList, Path.Combine(docsFolder, "Medications.csv"), outputFileDescription); + cc.Write(purchaseSummary, Path.Combine(docsFolder, "Intake.csv"), outputFileDescription); + cc.Write(orderSummary, Path.Combine(docsFolder, "Outtake.csv"), outputFileDescription); + +} + +internal IEnumerable ConvertMyDataRow(IEnumerable data) +{ + var groupData = data.SelectMany(dr => dr.ToList()) + .GroupBy(t => t.LineNbr) + .Select(t => new { Key = t.Key - 2, Values = t.ToList().Select(v => v.Value).ToArray() }); + var properties = groupData.Where(d => d.Key < 0) + .SelectMany(d => d.Values.Select(v => Regex.Replace(v, @"[\s()]", "") + .Replace("StartingQuantityBeginningofCurrentMonth", "StartQuantity") + .Replace("FinalQuantityEndofCurrentMonth", "FinalQuantity") + .Replace("MedicationTotalStartQuantity", "StartQuantity")).ToList()).ToArray(); + var medication = string.Empty; + var expandoData = groupData.Where(d => d.Key >= 0) + .Select((t, j) => + { + dynamic expando = new ExpandoObject(); + AddProperty(expando, "MedicineID", j); + int i = 0; + t.Values.ToList().ForEach(d => + { + if (properties[i] == "Medication") + { + if (string.IsNullOrEmpty(d)) + { + d = medication; + } + medication = d; + } + AddProperty(expando, properties[i], d ?? string.Empty); + i++; + }); + return expando; + }); + return expandoData; +} + +// Define other methods and classes here +internal class MyDataRow : List, IDataRow +{ +} + +public class MedicationBrand +{ + [CsvColumn(Name = "Medication", FieldIndex = 1)] + public string Medicine { get; set; } + [CsvColumn(Name = "Brand", FieldIndex = 2)] + public string Brand { get; set; } + [CsvColumn(FieldIndex = 3)] + public int Reorder {get;set;} +} + +public class Product +{ + internal string[] Row { get; set; } + [CsvColumn(Name = "MedicineID", FieldIndex = 1)] + public int index { get; set; } + internal string InvDateStr { get; set; } + public DateTime InvDate => !string.IsNullOrEmpty(InvDateStr) + ? DateTime.ParseExact(InvDateStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + [CsvColumn(Name = "Medication", FieldIndex = 2)] + public string Medicine { get; set; } + [CsvColumn(Name = "Brand", FieldIndex = 3)] + public string Brand { get; set; } + [CsvColumn(FieldIndex = 4)] + public string Label => string.IsNullOrEmpty(Brand) ? $"{Medicine} ({index})" : $"{Medicine} {Brand} ({index})"; + public string Dosage { get; set; } + public string Per { get; set; } + public string Unit { get; set; } + internal string StartStr { get; set; } + internal string RcvdStr { get; set; } + internal string OutStr { get; set; } + internal string FinalStr { get; set; } + [CsvColumn(Name = "StartingInventory", FieldIndex = 5)] + public int Start => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(StartStr) ? "0" : StartStr, "")); + public int Rcvd => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(RcvdStr) ? "0" : RcvdStr, "")); + public int Out => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(OutStr) ? "0" : OutStr, "")); + public int Final => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(FinalStr) ? "0" : FinalStr, "")); + [CsvColumn(FieldIndex = 6)] + public int InventoryReceived => Rcvd; + [CsvColumn(FieldIndex = 7)] + public int InventoryShipped => Out; + [CsvColumn(FieldIndex = 8)] + public int InventoryOnHand => Final; + [CsvColumn(FieldIndex = 9)] + public int MinimumRequired => Start; + [CsvColumn(FieldIndex = 10)] + public string NeedsReorder => Start == 0 ? "Yes" : "No"; + internal string ExpiryStr { get; set; } + [CsvColumn(FieldIndex = 11)] + public DateTime Expiry { get; set; } + public DateTime Purchased { get; set; } + public DateTime OrderDate => InvDate.AddMonths(1).AddDays(-1); + public string Notes { get; set; } + + internal PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + internal Regex regex = new Regex(@"[^\d]"); + + internal Product() + { + index = 0; + InvDateStr = DateTime.Today.ToString("M/yy"); + Medicine = string.Empty; + Brand = string.Empty; + Dosage = string.Empty; + Per = string.Empty; + Unit = string.Empty; + StartStr = "0"; + RcvdStr = "0"; + OutStr = "0"; + FinalStr = "0"; + Expiry = new DateTime(2018, 1, 1); + ExpiryStr = Expiry.ToString("M/yy"); + Purchased = new DateTime(2999, 12, 31); + Notes = string.Empty; + } + + public Product(int i, string[] row) + : this() + { + Row = row; + index = i + 1; + InvDateStr = row[0]; + Medicine = row[1]; + Dosage = row[2] ?? string.Empty; + Per = row[3] ?? string.Empty; + Unit = row[3] ?? string.Empty; + Unit = Unit.ToUpper().Contains("TUBE") ? "Tube" + : Unit.ToUpper().Contains("BOTTLE") ? "Bottle" + : Unit.ToUpper().Contains("VIAL") ? "Vial" + : Unit.ToUpper().Contains("TABLET") ? "Tablet" + : Unit.ToUpper().Contains("CAPSULE") ? "Capsule" + : Unit.ToUpper().Contains("LANCET") ? "Lancet" : Unit; + Per = !string.IsNullOrEmpty(Per) ? Per.Replace(Unit, "").TrimEnd("(s) ".ToCharArray()) : string.Empty; + StartStr = string.IsNullOrEmpty(row[4]) ? "0" : row[4]; + RcvdStr = string.IsNullOrEmpty(row[5]) ? "0" : row[5]; + OutStr = string.IsNullOrEmpty(row[6]) ? "0" : row[6]; + FinalStr = string.IsNullOrEmpty(row[7]) ? "0" : row[7]; + ExpiryStr = row[8]; + Notes = string.IsNullOrEmpty(row[9]) ? string.Empty : row[9]; + Expiry = !string.IsNullOrEmpty(ExpiryStr) + ? DateTime.ParseExact(ExpiryStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + Purchased = !string.IsNullOrEmpty(Notes) && Notes.StartsWith("Purchased") + ? DateTime.ParseExact(Notes.Substring(10), "M/d/yy", System.Globalization.CultureInfo.InvariantCulture) + : DateTime.Compare(Expiry, new DateTime(2018, 1, 1)) < 0 + ? Expiry.AddMonths(-6) : new DateTime(2018, 1, 1); + Notes = Notes.Replace($"Purchased {Purchased:M/d/yy}", ""); + } + + public Product(ExpandoObject expando, DateTime invDate) + : this() + { + InvDateStr = invDate.ToString("M/yy"); + var dictionary = expando as IDictionary; + dictionary.Keys.ToList() + .ForEach(k => + { + var value = Convert.ToString(dictionary[k]); + switch (k) + { + case "MedicineID": + index = Convert.ToInt32(value); + break; + case "Medicine": + case "Medication": + Medicine = value; + break; + case "MedicineBrand": + Brand = value; + break; + case "Dosage": + Dosage = value; + break; + case "PerBox": + Per = value; + break; + case "Unit": + Unit = ps.IsPlural(value) ? ps.Singularize(value) : value; + break; + case "Start": + case "StartQuantity": + StartStr = value; + break; + case "Received": + RcvdStr = value; + break; + case "Output": + OutStr = value; + break; + case "Final": + FinalStr = value; + break; + case "ExpirationDate": + ExpiryStr = Regex.Replace(value, @"[^\d/]", ""); + Expiry = !string.IsNullOrEmpty(ExpiryStr) + ? DateTime.ParseExact(ExpiryStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + break; + } + }); + if (string.IsNullOrEmpty(Unit)) + { + Unit = FindUnits(Per); + if (string.IsNullOrEmpty(Unit)) + Unit = FindUnits(Dosage); + } + } + + public string FindUnits(string unit) + { + return unit.ToUpper().Contains("TUBE") ? "Tube" + : unit.ToUpper().Contains("BOTTLE") ? "Bottle" + : unit.ToUpper().Contains("VIAL") ? "Vial" + : unit.ToUpper().Contains("TABLET") ? "Tablet" + : unit.ToUpper().Contains("CAPSULE") ? "Capsule" + : unit.ToUpper().Contains("LANCET") ? "Lancet" + : string.Empty; + } + + object ToDump() => new + { + MedicineID = index, + Medication = Medicine, + Brand, + Label, + Unit, + StartingInventory = Start, + InventoryReceived, + InventoryShipped, + InventoryOnHand, + MinimumRequired, + NeedsReorder, + Expiry = $"{Expiry.AddMonths(1).AddDays(-1):MM/dd/yy}" + }; +} + +public class Order +{ + internal string[] Row { get; set; } + [CsvColumn(Name = "MedicineID", FieldIndex = 1)] + public int index { get; set; } + internal string InvDateStr { get; set; } + public DateTime InvDate => !string.IsNullOrEmpty(InvDateStr) + ? DateTime.ParseExact(InvDateStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + [CsvColumn(Name = "Medication", FieldIndex = 2)] + public string Medicine { get; set; } + internal string Brand { get; set; } + [CsvColumn(FieldIndex = 3)] + public string Label => $"{Medicine} {Brand}"; + [CsvColumn(FieldIndex = 4)] + public string Customer => string.Empty; + internal string OutStr { get; set; } + [CsvColumn(Name = "Shipped", FieldIndex = 5)] + public int Out => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(OutStr) ? "0" : OutStr, "")); + [CsvColumn(Name = "Date", FieldIndex = 6)] + public DateTime OrderDate => InvDate.AddMonths(1).AddDays(-1); + + internal PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + internal Regex regex = new Regex(@"[^\d]"); + + internal Order() + { + index = 0; + InvDateStr = DateTime.Today.ToString("M/yy"); + Medicine = string.Empty; + Brand = string.Empty; + OutStr = "0"; + } + + public Order(ExpandoObject expando, DateTime invDate) + : this() + { + InvDateStr = invDate.ToString("M/yy"); + var dictionary = expando as IDictionary; + dictionary.Keys.ToList() + .ForEach(k => + { + var value = Convert.ToString(dictionary[k]); + switch (k) + { + case "MedicineID": + index = Convert.ToInt32(value); + break; + case "Medicine": + case "Medication": + Medicine = value; + break; + case "MedicineBrand": + Brand = value; + break; + case "Output": + OutStr = value; + break; + } + }); + } + + object ToDump() => new + { + MedicineID = index, + Medication = Medicine, + Brand, + Label, + Customer = "", + Shipped = Out, + Date = InvDate.AddMonths(1).AddDays(-1) + }; + +} + +public class Purchase +{ + internal string[] Row { get; set; } + [CsvColumn(Name = "MedicineID", FieldIndex = 1)] + public int index { get; set; } + internal string InvDateStr { get; set; } + public DateTime InvDate => !string.IsNullOrEmpty(InvDateStr) + ? DateTime.ParseExact(InvDateStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + [CsvColumn(Name = "Medication", FieldIndex = 2)] + public string Medicine { get; set; } + internal string Brand { get; set; } + [CsvColumn(FieldIndex = 3)] + public string Label => $"{Medicine} {Brand}"; + [CsvColumn(FieldIndex = 4)] + public string Supplier => string.Empty; + internal string RcvdStr { get; set; } + [CsvColumn(Name = "Received", FieldIndex = 5)] + public int Rcvd => Convert.ToInt32(regex.Replace(string.IsNullOrEmpty(RcvdStr) ? "0" : RcvdStr, "")); + internal string Notes { get; set; } + internal string ExpiryStr = ""; + internal DateTime Expiry => !string.IsNullOrEmpty(ExpiryStr) + ? DateTime.ParseExact(ExpiryStr, "M/yy", System.Globalization.CultureInfo.InvariantCulture) + : new DateTime(2999, 12, 31); + [CsvColumn(Name = "Date", FieldIndex = 6)] + public DateTime Purchased { get; set; } + + internal PluralizationService ps => PluralizationService.CreateService(new CultureInfo("en-US")); + internal Regex regex = new Regex(@"[^\d]"); + + internal Purchase() + { + index = 0; + InvDateStr = DateTime.Today.ToString("M/yy"); + Medicine = string.Empty; + Brand = string.Empty; + RcvdStr = "0"; + Purchased = new DateTime(2999, 12, 31); + } + + public Purchase(ExpandoObject expando, DateTime invDate) + : this() + { + InvDateStr = invDate.ToString("M/yy"); + Purchased = InvDate; + var dictionary = expando as IDictionary; + dictionary.Keys.ToList() + .ForEach(k => + { + var value = Convert.ToString(dictionary[k]); + switch (k) + { + case "MedicineID": + index = Convert.ToInt32(value); + break; + case "Medicine": + case "Medication": + Medicine = value; + break; + case "MedicineBrand": + Brand = value; + break; + case "Received": + RcvdStr = value; + break; + case "ExpirationDate": + ExpiryStr = Regex.Replace(value, @"[^\d/]", ""); + break; + case "Notes:": + var purchaseStr = !string.IsNullOrEmpty(value) && value.StartsWith("Purchased") + ? Regex.Replace(value, @"[^\d/]", "") + : string.Empty; + Purchased = !string.IsNullOrEmpty(purchaseStr) + ? DateTime.ParseExact(purchaseStr, "M/d/yy", System.Globalization.CultureInfo.InvariantCulture) + : DateTime.Compare(Expiry, new DateTime(2018, 1, 1)) < 0 + ? Expiry.AddMonths(-6) : new DateTime(2018, 1, 1); ; + break; + } + }); + } + + object ToDump() => new + { + MedicineID = index, + Medication = Medicine, + Brand, + Label, + Supplier = "", + Received = Rcvd, + Date = Purchased + }; +} + +public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue) +{ + // ExpandoObject supports IDictionary so we can extend it like this + var expandoDict = expando as IDictionary; + if (expandoDict.ContainsKey(propertyName)) + expandoDict[propertyName] = propertyValue; + else + expandoDict.Add(propertyName, propertyValue); +} \ No newline at end of file diff --git a/SonarQube API/Quboo Integration API.linq b/SonarQube API/Quboo Integration API.linq new file mode 100644 index 0000000..83aa44c --- /dev/null +++ b/SonarQube API/Quboo Integration API.linq @@ -0,0 +1,74 @@ + + RestSharp + RestSharp + Newtonsoft.Json + + +void Main() +{ + Score(Severity.Critical, 5, 18).Dump(); + ScoreAlt(Severity.Critical, 5, 18).Dump(); + awardPoints("jchau", Severity.Critical, 5, 18); + Score(Severity.Major, 15, 5).Dump(); + ScoreAlt(Severity.Major, 15, 5).Dump(); + awardPoints("jchau", Severity.Major, 15, 5); + Score(Severity.Major, 15, 4).Dump(); + awardPoints("jpollard", Severity.Major, 15, 4); + Score(Severity.Major, 10, 2).Dump(); + awardPoints("aschey", Severity.Major, 10, 2); + Score(Severity.Major, 10).Dump(); + awardPoints("tscanlan", Severity.Major, 10); +} + +// Define other methods and classes here + +public enum Severity +{ + Info = 1, + Minor = 2, + Major = 5, + Critical = 7, + Blocker = 10 +} + +public int Score(Severity severity, int debt, int items = 1) +{ + $"Math.Max(1, {debt} / 10 * {(int)severity}) * {items} items".Dump(); + return Math.Max(1, debt / 10 * (int)severity) * items; +} + +public int ScoreAlt(Severity severity, int debt, int items = 1) +{ + $"Math.Max(1, {debt} * {(int)severity} / 10) * {items} items".Dump(); + return Math.Max(1, debt * (int)severity / 10) * items; +} + +public void awardPoints(string playerLogin, Severity severity, int debt, int items = 1) +{ + string BaseUrl = @"https://api.quboo.io/score/generic"; + RestClient client = new RestClient(); + client.BaseUrl = new Uri(BaseUrl); + RestRequest request = new RestRequest(); + request.Method = Method.PUT; + request.AddHeader("x-quboo-access-key", "FgtzhUSwAdsf4sGpM0kzXePP"); + request.AddHeader("x-quboo-secret-key", "AwzF8dreEwkGemRS"); + request.AddHeader("Content-Type", " application/json"); + + var qubooBody = new + { + playerLogin = playerLogin, + uniqueId = Guid.NewGuid(), + description = $"Resolving {items} {debt}min {severity} items", + score = Score(severity, debt, items) + }; + request.AddJsonBody(qubooBody); + var result = client.Execute(request); + if (!result.IsSuccessful && result.ErrorMessage != null) + { + result.ErrorMessage.Dump(); + } + else + { + JsonConvert.SerializeObject(JsonConvert.DeserializeObject(result.Content), Newtonsoft.Json.Formatting.Indented).Dump(); + } +} \ No newline at end of file diff --git a/SonarQube API/SonarQube Just Summarize Issue Counts.linq b/SonarQube API/SonarQube Just Summarize Issue Counts.linq new file mode 100644 index 0000000..b697f14 --- /dev/null +++ b/SonarQube API/SonarQube Just Summarize Issue Counts.linq @@ -0,0 +1,99 @@ + + +var newIssueList = Regex.Replace(@"Cube Engine/Strata.CubeEngine.UserDefinedFunctions +0 +Jazz AP Service/Jazz AP Service +30 +ModelCacheWebService/ModelCacheWebService +0 +OData +0 +Optimization/Strata.Optimization +0 +Strata Administrator +4 +Strata Cube Reporter/Strata.CubeReporter +0 +Strata Spoon/Strata.Spoon +0 +Strata Template Architect +0 +Strata.Base +1 +Strata.Base.Internal +0 +Strata.CS.Base +2 +Strata.CS.Jazz.ABB +252 +Strata.CS.Jazz.Biz +331 +Strata.CS.Jazz.Biz.CCI +49 +Strata.CS.Jazz.Biz.DSS.APReimbursementEngine +0 +Strata.CS.Jazz.Biz.DSS.Episodes +2 +Strata.CS.Jazz.Biz.DSS.Episodes.EpisodeDefinition +1 +Strata.CS.Jazz.Biz.DSS.Episodes.EpisodeVisualizer +3 +Strata.CS.Jazz.Biz.DSS.HPAdmin +9 +Strata.CS.Jazz.Biz.Notifications +0 +Strata.CS.Jazz.Biz.Snapshot/Properties +0 +Strata.CS.Jazz.Biz.StarterSet +43 +Strata.CS.Jazz.Dimensionality +0 +Strata.CS.Jazz.FP +0 +Strata.CS.Jazz.Ideas +0 +Strata.CS.Jazz.UI +3 +Strata.DataStudio20/Strata.DataStudio20 +0 +Strata.Entity.Base +0 +Strata.Hangfire.Service +0 +Strata.Jazz.Biz +1 +Strata.Jazz.FoolsGold.Biz +0 +Strata.Jazz.Hangfire +1 +Strata.Jazz.Hangfire.WebServices +0 +Strata.Jazz.Midas.Biz +19 +Strata.Jazz.Midas.Web +13 +Strata.Jazz.MVC +0 +Strata.Jazz.UI +0 +Strata.Jazz.Web +207 +Strata.Reporting.ExcelReporter40 +0 +Strata.Reporting.Opus +0 +Strata.Score +2 +Strata.Score.ConfigTool/Strata.Score.ConfigTool.Biz +0 +Strata.Score.DimensionEditor +0 +Strata.Score.DimensionEditor20 +0 +Strata.Score.DimensionEditor20.Biz +0 +", @"\r\n([\d]*\r\n)", "\t$1").Replace("\r\n", "\r").Split('\r') +.Where(x => !string.IsNullOrEmpty(x)) +.Select(x => new { project = x.Split('\t')[0], issues = x.Split('\t')[1] }) +.Where(x => x.issues != "0"); +newIssueList.Dump(); \ No newline at end of file diff --git a/SonarQube API/SonarQube WebService API.linq b/SonarQube API/SonarQube WebService API.linq new file mode 100644 index 0000000..743cfd1 --- /dev/null +++ b/SonarQube API/SonarQube WebService API.linq @@ -0,0 +1,1071 @@ + + Newtonsoft.Json + RestSharp + RestSharp + Newtonsoft.Json + Newtonsoft.Json.Linq + RestSharp.Authenticators + Newtonsoft.Json.Converters + System.Dynamic + System + System.Linq.Dynamic + System.Web + + +private string BaseUrl = "https://sonarqube.sdt.local"; +private Dictionary ruleDictionary; +//private DateTime BeginningOfTheYear = new DateTime(DateTime.Now.Year, 1, 1); +private static DateTime CreatedBefore = new DateTime(2020, 8, 13); +private static DateTime StartOfSprint = CreatedBefore.AddDays(1); +private static DateTime EndOfSprint = CreatedBefore.AddDays(15); +private Dictionary Parameters = new Dictionary +{ + { "projects", ""}, +// {"types","BUG,VULNERABILITY,SECURITY_HOTSPOT"}, +// {"severities","BLOCKER,CRITICAL,MAJOR"}, +// {"statuses", "OPEN,CONFIRMED,REOPENED,TO_REVIEW,IN_REVIEW"}, + {"resolutions", "FIXED"}, + {"s", "CLOSE_DATE"}, + {"languages", null}, + {"createdBefore", $"{CreatedBefore:yyyy-MM-dd}"}, + //{"createdAfter", null}, // $"{BeginningOfTheYear:yyyy-MM-dd}" + {"assignees", null} +}; + +#region Enumerations + +public string GetName(Type enumType, int value) +{ + return Enum.GetName(enumType, value); +} + +public enum SonarType +{ + BUG, + VULNERABILITY, + CODE_SMELL, + SECURITY_HOTSPOT +} + +public enum SonarSeverity +{ + BLOCKER, + CRITICAL, + MAJOR, + MINOR, + INFO +} + +public enum QubooSeverity +{ + BLOCKER = 10, + CRITICAL = 7, + MAJOR = 5, + MINOR = 2, + INFO = 1 +} + +public enum SonarResolution +{ + UNRESOLVED, + FIXED, + WONTFIX, + FALSE_POSITIVE, + REMOVED +} + +public enum SonarStatus +{ + OPEN, + TO_REVIEW, + IN_REVIEW, + REVIEWED, + REOPENED, + CONFIRMED, + RESOLVED, + CLOSED +} + +#endregion + +public Dictionary> GroupUsers = new Dictionary>(); + +void Main() +{ + RestClient client = new RestClient(); +// var projects = ListProjects(client); +// projects.Dump(); +// return; + new { CreatedBefore, StartOfSprint, EndOfSprint}.Dump("Campaign"); + PopulateUserGroups(); + var value = GetName(typeof(SonarType), (int)SonarType.BUG); + //GetJson(client, "/api/languages/list").Dump(); + //ListWebServices(client).Dump("List WebServices"); + var rules = GetRules(client) + .OrderBy(l => l.repo).ThenBy(l => l.key); + ruleDictionary = rules + .ToDictionary(r => r.key, r => $"{r.name} ({r.severity})"); + var parameters = new List { + new RestSharp.Parameter("additionalFields","_all", ParameterType.QueryString) + }; + parameters.AddRange(Parameters.Where(p => !string.IsNullOrEmpty(p.Value)) + .Select(p => new RestSharp.Parameter(p.Key, p.Value, ParameterType.QueryString))); + var issues = GetIssues(client, parameters) + .Where(i => i.closeDate >= StartOfSprint && i.closeDate <= EndOfSprint) + // .Where(i => i.closeDate >= CreatedBefore.AddDays(-14) && i.closeDate <= CreatedBefore) + ; + if (1 == 0) + { + if (parameters.Select(p => p.Name).Contains("projects")) + { + $"{parameters.First(p => p.Name == "projects").Value} ({issues.Count()} Issues)".Dump(); + } + else + { + $"{issues.Count()} Issues".Dump(); + } + } + issues + .Where(i => i.assignee != null) + .Select(i => new + { + i.severity, + i.project, + i.type, + i.status, + i.resolution, + i.assignee, + team = GetUserGroup(i.assignee), + i.debt, + i.effort, + i.closeDate, + score = Score(i.severity, i.debt) + }) + //.GroupBy(i => new {i.assignee, i.severity, i.type}, (g,d) => d) + .OrderBy(i => i.team) + .ThenBy(i => i.project) + .ThenBy(i => i.assignee) + .ThenBy(i => i.severity) + .ThenBy(i => i.type) + .Dump(); + //issues.Take(10).Dump("Dump 10 issues"); + //ReportIssues(issues); +} + +public int Score(string severity, string debt, int items = 1) +{ + if (debt == null || severity == null) return 0; + var qSeverity = (QubooSeverity)Enum.Parse(typeof(QubooSeverity), severity); + var iDebt = int.Parse(Regex.Replace(debt, @"[^\d]", "")); + return Score(qSeverity, iDebt, items); +} + +public int Score(QubooSeverity severity, int debt, int items = 1) +{ + //$"Math.Max(1, {debt} / 10 * {(int)severity}) * {items} items".Dump(); + return Math.Max(1, debt / 10 * (int)severity) * items; +} + +void ReportIssues(IEnumerable issues) +{ + var byTeam = issues + .OrderBy(i => GetUserGroup(i.assignee ?? i.author ?? "")) + .ThenBy(i => i.component) + .ThenBy(i => i.type) + .ThenBy(i => i.severity) + .Select(i => new + { + assignee = GetUserGroup(i.assignee ?? i.author ?? "Not assigned"), + i.component, + i.message, + i.type, + i.status, + i.severity, + i.effort, + i.creationDate, + i.closeDate, + lineNumber = i.line, + i.taglist + }) + .GroupBy(i => i.assignee, (g, d) => new TeamGrouper( + g, + d.GroupBy(dd => new { type = Path.GetExtension(dd.component), dd.component }, (gg, gd) => + new ComponentGrouper( + gg.type, + gg.component, + gd.GroupBy(yy => new + { + yy.creationDate.Year, + yy.creationDate.Month, + yy.type, + yy.status, + yy.severity + }, (gdk, gdd) => + new SummaryGrouper( + gdk.Year, + gdk.Month, + gdk.status, + gdk.type, + gdk.severity, + gdd.Count() + )).OrderByDescending(yy => yy.Year) + .ThenByDescending(yy => yy.Month) + )) + .GroupBy(dd => dd.Solution, (xg, xd) => new SolutionGrouper + ( + xg, + xd.GroupBy(y => y.Project, (yg, yd) => new ProjectGrouper + ( + yg, + yd.OrderBy(x => x.Path).ThenBy(x => x.FileName) + )).OrderBy(x => x.Project) + )) + .OrderBy(dd => dd.Solution) + )) + .OrderBy(i => i.Team).ToList(); + byTeam.ForEach(team => + { + team.Solutions.ForEach(solution => + { + solution.Solution.Dump().DumpX(team.Team); ; + solution.Projects.Dump(10).DumpX(team.Team); + }); + }); +} + +#region User Group Definition + +public void PopulateUserGroups() +{ + GroupUsers.Add("Architecture", new List { }); + GroupUsers.Add("The A-Team", new List { "tlamb", "tdebolt" }); + GroupUsers.Add("Ryan King", new List { "rreimer", "jpollard", "chelm", "aschey" }); + GroupUsers.Add("Cube Killers", new List { "yrhee", "dforero", "lbehmer" }); + GroupUsers.Add("Kobra Kaizer", new List { "mschmidt", "nbuckle", "fsweis", "jmorales" }); + GroupUsers.Add("Team Sloth", new List { "myoung", "bkrehl", "nnawale", "lrenadesouza", "nleroy" }); + GroupUsers.Add("Team Thanos", new List { "bwells", "zbruin", "zhare", "mwynne", "mdeboer", "jnarofsky" }); + GroupUsers.Add("Platform", new List { "mleitch", "awolek", "jrapp", "cbello", "jchau", "hgutta", "ljian" }); + GroupUsers.Add("Boo", new List { "kferchuk", "akuten", "hvladyka", "vfay" }); + GroupUsers.Add("Jedi", new List { "akost", "sdominska", "tparashchak", "opalamar" }); + GroupUsers.Add("Pokemon", new List { "okrainyk", "mstepanov", "yantoniuk" }); + GroupUsers.Add("Tropic Thunder", new List { "ainzhyievskyi", "ihalenok", "dpanteliuk", "akorchynskyi" }); + GroupUsers.Add("Bee Swarmers", new List { "tscanlan", "cburke", "sxie" }); + GroupUsers.Add("The Moustache", new List { "wrusinko" }); +} + +public string GetUserGroup(string user) +{ + var group = GroupUsers.Where(gu => gu.Value.Contains(user)).FirstOrDefault(); + return group.Key ?? $"unknown {user}"; +} + +#endregion + +#region Issues Report + +public class SolutionGrouper +{ + public string Solution { get; set; } + public List Projects { get; set; } + + public SolutionGrouper(string solution, IOrderedEnumerable projects) + { + Solution = solution; + Projects = projects.ToList(); + } +} + +public class ProjectGrouper +{ + public string Project { get; set; } + public IOrderedEnumerable Issues { get; set; } + + public ProjectGrouper(string project, IOrderedEnumerable issues) + { + Project = project; + Issues = issues; + } +} + +public class TeamGrouper +{ + public string Team { get; set; } + public List Solutions { get; set; } + + public TeamGrouper(string team, IOrderedEnumerable solutions) + { + Team = team; + Solutions = solutions.ToList(); + } +} + +public class ComponentGrouper +{ + public string Solution { get; set; } + public List Issues { get; set; } + public string Component { get; set; } + public string Path { get; set; } + public string Project { get; set; } + public string FileName { get; set; } + public string Extension { get; set; } + public string Url { get; set; } + + public ComponentGrouper() + { + + } + + public ComponentGrouper(string type, string component, IOrderedEnumerable issues) + { + Component = component.Split(new[] { ':' }).Last().Replace('/', '\\'); + Solution = component.Split(new[] { ':' }).First(); + Extension = type.TrimStart(new[] { '.' }); + var filePath = $@"D:\{Component}"; + Path = System.IO.Path.GetDirectoryName(filePath); + var pathParts = Path.Split(System.IO.Path.DirectorySeparatorChar); + //pathParts.Dump(); + if (new[] { "Code", "Internal Tools", "src" }.Contains(pathParts[1])) + { + Project = pathParts.Skip(2).First(); + Path = string.Join($"{System.IO.Path.DirectorySeparatorChar}", pathParts.Skip(2)); + } + else + { + Project = pathParts.Skip(1).First(); + Path = string.Join($"{System.IO.Path.DirectorySeparatorChar}", pathParts.Skip(1)); + } + FileName = System.IO.Path.GetFileName(filePath); + Issues = issues.ToList(); + Url = HttpUtility.HtmlEncode($@"{component}"); + } + object ToDump() => new + { + Issues, + Path, + FileName = new Hyperlinq($@"https://sonarqube.sdt.local/code?id={Url}", FileName) + }; +} + +public class SummaryGrouper +{ + public int Year { get; set; } + public int Month { get; set; } + public string Status { get; set; } + public string Type { get; set; } + public string Severity { get; set; } + public int Items { get; set; } + + public SummaryGrouper() + { + + } + public SummaryGrouper(int year, int month, string status, string type, string severity, int count) + { + Year = year; + Month = month; + Status = status; + Type = type; + Severity = severity; + Items = count; + } + + object ToDump() => new + { + Date = $"{(new DateTime(Year, Month, 1)):yyyy/MM}", + Status, + Type, + Severity, + Count = $"{Items}" + }; +} + +#endregion + +public void WriteReport(List issues) +{ + var reports = issues + .GroupBy(sdm => new + { + author = sdm.author ?? sdm.assignee ?? "", + project = sdm.project, + componentKey = sdm.componentKey, + status = sdm.status ?? "", + severity = sdm.severity ?? "", + resolution = sdm.resolution ?? "", + type = sdm.type, + rule = sdm.rule + }, (g, d) => new IssueReport + { + group = new IssueGroup + { + author = g.author, + project = g.project, + componentKey = g.componentKey, + status = g.status, + severity = g.severity, + resolution = g.resolution, + type = g.type, + rule = g.rule, + issues = d.Count() + }, + issues = d.Select(issue => (IssueReportIssue)issue).ToList() + }) + .OrderBy(r => r.group.author) + .ThenBy(r => r.group.project) + .ToList(); + reports.ForEach(report => + { + //"".PadLeft(40, '―').Dump(); + // report.group.Dump(); + var issueList = report.issues + .GroupBy(i => new { i.message, i.debt, i.effort, i.fileType, i.assignee, i.comment }, (g, d) => new + { + g.message, + debt = g.debt * d.Count(), + effort = g.effort * d.Count(), + g.fileType, + g.assignee, + g.comment, + createdAt = $"{d.Min(i => i.createdAt):d}", + closedAt = $"{d.Max(i => i.closedAt):d}", + daysToClose = (int)d.Max(i => i.closedAt).Subtract(d.Min(i => i.createdAt)).TotalDays, + occurred = d.Count() + }); + new + { + report.group, + issueList + }.Dump(); + // if (issueList.Count() > 1000) + // { + // issueList + // .Select((issue, index) => new { issue, index }) + // .GroupBy(x => x.index / 1000, (key, y) => y.Select(z => z.issue)) + // .Dump(); + // } + // else + // { + // issueList.Dump(); + // } + }); +} + +public void SummarizeIssues(RestClient client) +{ + var types = new[] { "VULNERABILITY", "BUG", "CODE_SMELL" }; + var severities = new[] { "BLOCKER", "CRITICAL", "MAJOR" }; + var issues = GetIssues(client); + var CiStarterSet = issues + .Where(i => i.status != "CLOSED" + && new[] { "BLOCKER", "CRITICAL", "MAJOR" }.Contains(i.severity) + ); + CiStarterSet + .OrderBy(i => i.rule == "csharpsquid:S3776" ? 99 + : i.severity == "MAJOR" ? 2 + : i.severity == "BLOCKER" ? 0 + : i.severity == "CRITICAL" ? 1 : 99) + .GroupBy(i => i.component +, (g, d) => new +{ + key = g, + critical = d.Count(x => x.severity == "CRITICAL"), + ageInYears = (int)(d.Min(x => DateTime.Now.Subtract(x.creationDate).TotalDays) / 365), + team = "" +}) + .OrderByDescending(i => i.ageInYears) + .ThenBy(i => i.critical) + .ThenBy(i => i.key) + //.ThenBy(i => i.key) + .Dump(); +} + +JObject GetVersion(RestClient client) +{ + return GetJson(client, "/api/server/system"); +} + +#region Rule Management + +List GetRules(RestClient client) +{ + List rules = new List(); + var pageNo = 1; + while (true) + { + var info = ListRules(client, pageNo); + if (info == null) break; + var deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(info)).rules; + if (deserialized == null || !deserialized.Any()) break; + pageNo += 1; + var page = deserialized; //.Where(i => i.rule.StartsWith("csharpsquid:")); + if (!page.Any()) continue; + rules.AddRange(page); + } + return rules; +} + +JObject ListRules(RestClient client, int page = 1, int pageSize = 500) +{ + return GetJson(client, "/api/rules/search", new List { + new Parameter("ps", pageSize, ParameterType.QueryString), + new Parameter("p", page, ParameterType.QueryString) + }); +} + +public class Rule +{ + public string key { get; set; } + public string repo { get; set; } + public string name { get; set; } + public DateTime createdAt { get; set; } + public string htmlDesc { get; set; } + public string mdDesc { get; set; } + public string severity { get; set; } + public bool isBlockerIssue => severity == "BLOCKER"; + public bool isCriticalIssue => severity == "CRITICAL"; + public bool isMajorIssue => severity == "MAJOR"; + public string status { get; set; } + public string internalKey { get; set; } + public bool isTemplate { get; set; } + public List tags { get; set; } + public List sysTags { get; set; } + public string lang { get; set; } + public string langName { get; set; } + public List @params { get; set; } + public string defaultDebtRemFnType { get; set; } + public string defaultDebtRemFnCoeff { get; set; } + public bool debtOverloaded { get; set; } + public string debtRemFnType { get; set; } + public string debtRemFnCoeff { get; set; } + public string defaultRemFnType { get; set; } + public string defaultRemFnGapMultiplier { get; set; } + public string remFnType { get; set; } + public string remFnGapMultiplier { get; set; } + public bool remFnOverloaded { get; set; } + public string scope { get; set; } + public bool isExternal { get; set; } + public string type { get; set; } + public bool isVulnerability => type == "VULNERABILITY"; + public bool isBug => type == "BUG"; + public bool isCodeSmell => type == "CODE_SMELL"; +} + +#endregion + +#region User Management + +JObject ListUsers(RestClient client) +{ + return GetJson(client, "/api/users/search"); +} + +public void AddNewUsers(RestClient client) +{ + var names = @"User Name Email First Name Last Name +sdt\ainzhyievskyi ainzhyievskyi@stratadecision.com Artur Inzhyievskyi +sdt\dpanteliuk dpanteliuk@stratadecision.com Dmytro Panteliuk +sdt\vivanov vivanov@stratadecision.com Vadym Ivanov +sdt\akorchynskyi akorchynskyi@stratadecision.com Andrii Korchynskyi +sdt\akost aksot@stratadecision.com Andrii Kost +sdt\tparashchak tparashchak@stratadecision.com Taras Parashchak +sdt\sdominska sdominska@stratadecision.com Svitlana Dominska +sdt\opalamar opalamar@stratadecision.com Oleksii Palamar +sdt\vfay vfay@stratadecision.com Vasyl Fay +sdt\kferchuk kferchuk@stratadecision.com Kostyantyn Ferchuk +sdt\hvladyka hvladyka@stratadecision.com Halyna Vladyka +sdt\ihalenok ihalenok@stratadecision.com Iryna Halenok +sdt\akuten akuten@stratadecision.com Andrii Kuten +sdt\yantoniuk yantoniuk@stratadecision.com Yurii Antoniuk +sdt\mstepanov mstepanov@stratadecision.com Mykhailo Stepanov" + .Replace("\r\n", "\r").Split('\r').Skip(1) + .Select(x => x.Split('\t')).ToList() + .ConvertAll(x => new NewUser + { + name = $"{x[2]} {x[3]}", + login = x[0].Replace(@"sdt\", ""), + password = "Password1", + email = x[1] + }); + var users = ListUsers(client); + var logins = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(users)).users; + names.Where(n => !logins.Select(l => l.login).Contains(n.login)).Dump(); + names.Where(n => !logins.Select(l => l.login).Contains(n.login)).ToList() + .ForEach(n => CreateUser(client, n)); +} + +void CreateUser(RestClient client, NewUser user) +{ + client.BaseUrl = new Uri(BaseUrl); + client.Authenticator = new HttpBasicAuthenticator("admin", "admin"); + var request = new RestRequest(); + request.Resource = "/api/users/create"; + request.Method = Method.POST; + request.RequestFormat = DataFormat.Json; + request.AddParameter(new Parameter("login", user.login, ParameterType.QueryString)); + request.AddParameter(new Parameter("password", user.password, ParameterType.QueryString)); + request.AddParameter(new Parameter("password_confirmation", user.password, ParameterType.QueryString)); + request.AddParameter(new Parameter("name", user.name, ParameterType.QueryString)); + request.AddParameter(new Parameter("email", user.email, ParameterType.QueryString)); + request.Dump(); + var response = client.Execute(request); + response.Dump(); + +} + +public class User +{ + public string login { get; set; } + public string name { get; set; } +} + +public class NewUser : User +{ + public string email { get; set; } + public string password { get; set; } +} + +#endregion + +#region Web Services + +public void DumpWebServices(RestClient client) +{ + var services = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(ListWebServices(client))).webServices; + services.Dump(); +} + +JObject ListWebServices(RestClient client) +{ + return GetJson(client, "/api/webservices/list"); +} + +#endregion + +#region Issue Management + +List GetIssues(RestClient client, List parameters = null) +{ + List issues = new List(); + var pageNo = 1; + while (true) + { + var info = ListIssues(client, pageNo, parameters); + if (info == null) break; + pageNo += 1; + var root = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(info)); + if (root.errors?.Any() ?? false) + { + root.errors.Dump(); + break; + } + var deserialized = root.issues; + if (deserialized == null || !deserialized.Any()) break; + issues.AddRange(deserialized); + } + return issues; +} + +JObject ListIssues(RestClient client, int page = 1, List parameters = null, int pageSize = 500) +{ + var queryParameters = new List { + new Parameter("ps", pageSize, ParameterType.QueryString), + new Parameter("p", page, ParameterType.QueryString), + new Parameter("additionalFields", "comments", ParameterType.QueryString) + }; + if (parameters?.Any() ?? false) + queryParameters.RemoveAll(qp => parameters.Select(p => p.Name).Contains(qp.Name)); + if (parameters != null) + queryParameters.AddRange(parameters); + return GetJson(client, "/api/issues/search", queryParameters); +} + +#endregion + +#region Project Management + +//List GetProjects(RestClient client, List parameters = null) +//{ +// List issues = new List(); +// var pageNo = 1; +// while (true) +// { +// var info = ListProjects(client, pageNo, parameters); +// if (info == null) break; +// pageNo += 1; +// var root = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(info)); +// if (root.errors?.Any() ?? false) +// { +// root.errors.Dump(); +// break; +// } +// var deserialized = root.issues; +// if (deserialized == null || !deserialized.Any()) break; +// issues.AddRange(deserialized); +// } +// return issues; +//} + +JObject ListProjects(RestClient client, int page = 1, List parameters = null, int pageSize = 500) +{ + var queryParameters = new List { + new Parameter("ps", pageSize, ParameterType.QueryString), + new Parameter("p", page, ParameterType.QueryString) + }; + if (parameters?.Any() ?? false) + queryParameters.RemoveAll(qp => parameters.Select(p => p.Name).Contains(qp.Name)); + if (parameters != null) + queryParameters.AddRange(parameters); + return GetJson(client, "/api/projects/search", queryParameters); +} + +#endregion + +#region Data Classes + +public class IssueComment +{ + public string key { get; set; } + public string login { get; set; } + public string htmlText { get; set; } + public string markdown { get; set; } + public bool updatable { get; set; } + public DateTime createdAt { get; set; } +} + +public class IssueGroup +{ + public string project { get; set; } + public string componentKey { get; set; } + public string author { get; set; } + public string severity { get; set; } + public string status { get; set; } + public string type { get; set; } + public string resolution { get; set; } + public string rule { get; set; } + public int issues { get; set; } + public object ToDump() => new[] { this }; +} + +public class Issue +{ + public string severity { get; set; } + public SonarSeverity severityId => (SonarSeverity)Enum.Parse(typeof(SonarSeverity), severity); + public bool isBlocker => severityId == SonarSeverity.BLOCKER; + public bool isCritical => severityId == SonarSeverity.CRITICAL; + public bool isMajor => severityId == SonarSeverity.MAJOR; + public bool isMinor => severityId == SonarSeverity.MINOR; + public bool isInfo => severityId == SonarSeverity.INFO; + public string status { get; set; } + public SonarStatus statusId => (SonarStatus)Enum.Parse(typeof(SonarStatus), status); + public bool isOpen => statusId == SonarStatus.OPEN; + public bool isClosed => statusId == SonarStatus.CLOSED; + public bool isReviewed => statusId == SonarStatus.REVIEWED; + public bool isResolved => statusId == SonarStatus.RESOLVED; + public bool isInReview => statusId == SonarStatus.TO_REVIEW; + public string type { get; set; } + public SonarType typeId => (SonarType)Enum.Parse(typeof(SonarType), type); + public bool isVulnerability => typeId == SonarType.VULNERABILITY; + public bool isSecurityHotspot => typeId == SonarType.SECURITY_HOTSPOT; + public bool isBug => typeId == SonarType.BUG; + public bool isCodeSmell => typeId == SonarType.CODE_SMELL; + public string resolution { get; set; } + public SonarResolution resolutionId => (SonarResolution)Enum.Parse(typeof(SonarResolution), resolution); + public bool wontfix => resolutionId == SonarResolution.WONTFIX; + public List comments { get; set; } + public string message { get; set; } + public string key { get; set; } + public string rule { get; set; } + public string debt { get; set; } + public string project { get; set; } + public string component { get; set; } + internal string[] componentParts => component.Split('/'); + public string componentKey => componentParts.Count() > 3 && componentParts[1] == "Strata.Jazz.Web" && componentParts[2] == "Areas" + ? Regex.Replace(componentParts[3], "^Strata.", "") + : componentParts.Count() > 3 && componentParts[1] == "Strata.Jazz.Web" && componentParts[2] != "Areas" + ? Regex.Replace(componentParts[2], "^Strata.", "") + : componentParts.Count() > 1 + ? Regex.Replace(componentParts[1], "^Strata.", "") + : component; + public string fileType => component.Substring(component.LastIndexOf('.') + 1); + public int line { get; set; } + public TextRange textRange { get; set; } + public List flows { get; set; } + public string effort { get; set; } + public string assignee { get; set; } + public string author { get; set; } + // public string hash { get; set; } + public List tags { get; set; } + public string taglist => string.Join(", ", tags); + public DateTime creationDate { get; set; } + public int ageInYears => (int)DateTime.Now.Subtract(creationDate).TotalDays / 365; + public DateTime updateDate { get; set; } + // public string organization { get; set; } + public bool fromHotspot { get; set; } + public DateTime? closeDate { get; set; } + // public string __invalid_name__effort { get; set; } + + public static explicit operator UserQuery.IssueReportIssue(Issue issue) + { + var debt = issue.debt ?? "0"; + var effort = issue.effort ?? "0"; + var r1 = new Regex(@"[^\d]*"); + var r2 = new Regex(@"[\d]*"); + var debtInterval = 1; + switch (r2.Replace(debt, "")) + { + case "min": debtInterval = 1; break; + case "day": debtInterval = 60 * 24; break; + default: debtInterval = Int32.MaxValue; break; + } + var effortInterval = 1; + switch (r2.Replace(effort, "")) + { + case "min": effortInterval = 1; break; + case "day": effortInterval = 60 * 24; break; + default: effortInterval = Int32.MaxValue; break; + } + var i = new UserQuery.IssueReportIssue + { + message = issue.message, + debt = Convert.ToInt32(r1.Replace(debt, "")) * debtInterval, + effort = Convert.ToInt32(r1.Replace(effort, "")) * effortInterval, + fileType = issue.fileType, + assignee = issue.comments.FirstOrDefault()?.login ?? "", + comment = issue.comments.FirstOrDefault()?.markdown ?? "", + createdAt = issue.creationDate, + closedAt = issue.comments.FirstOrDefault()?.createdAt ?? issue.closeDate ?? DateTime.Now + }; + return i; + } + +} + +public class IssueReportGroup +{ + public string message { get; set; } + public int debt { get; set; } + public int effort { get; set; } + public string fileType { get; set; } + public string assignee { get; set; } + public string comment { get; set; } +} + +public class IssueReportIssue : IssueReportGroup +{ + public DateTime createdAt { get; set; } + public DateTime closedAt { get; set; } + public int daysToClose { get; set; } + public int occurred { get; set; } +} + +public class IssueReport +{ + public IssueGroup group; + public List issues; +} + +#endregion + +void Other(RestClient client) +{ + var issues = GetJson(client, "/api/issues/search?assignees=tlamb&severities=BLOCKER,CRITICAL"); + JsonConvert.DeserializeObject(JsonConvert.SerializeObject(issues)).issues + .GroupBy(i => new + { + i.rule, + i.project, + i.type + }, (g, d) => new + { + issue = new + { + type = g.type, + id = g.rule, + project = g.project, + severity = d.First().severity, + message = d.First().message, + issues = d.Count() + }, + issues = d.Select(i => new + { + i.status, + i.component, + i.line, + i.message, + i.textRange, + i.effort, + i.debt, + i.key + }) + }) + .Dump(); +} + +// Define other methods and classes here + +#region RestSharp Helpers + +JObject GetJson(RestClient client, string something, List parameters = null) +{ + client.BaseUrl = new Uri(BaseUrl); + RestRequest request = new RestRequest(); + request.Resource = something; + request.Method = Method.GET; + if (parameters?.Any() ?? false) + request.Parameters.AddRange(parameters); + return JObject.Parse(client.Execute(request).Content); +} + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +#endregion + +#region json2csharp + +public class Paging +{ + public int pageIndex { get; set; } + public int pageSize { get; set; } + public int total { get; set; } +} + +public class TextRange +{ + public int startLine { get; set; } + public int endLine { get; set; } + public int startOffset { get; set; } + public int endOffset { get; set; } + + object ToDump() => startLine != endLine + ? $"L{startLine}:{endLine},O{startOffset}:{endOffset}" + : $"L{startLine},O{startOffset}:{endOffset}"; +} + +public class FlowComponent +{ + public string component { get; set; } + public TextRange textRange { get; set; } + public string msg { get; set; } +} + +public class Flow +{ + public List locations { get; set; } +} + +public class SonarError +{ + public string msg { get; set; } +} + +public class Component +{ + public string organization { get; set; } + public string key { get; set; } + public string uuid { get; set; } + public bool enabled { get; set; } + public string qualifier { get; set; } + public string name { get; set; } + public string longName { get; set; } + public string path { get; set; } +} + +public class RootObject +{ + public int total { get; set; } + public int p { get; set; } + public int ps { get; set; } + public UserQuery.Paging paging { get; set; } + public int effortTotal { get; set; } + public int debtTotal { get; set; } + // public int majorIssues => issues.Count(i => i.severity == "MAJOR"); + // public int criticalIssues => issues.Count(i => i.severity == "CRITICAL"); + public int vulnerabilityIssues => issues.Count(i => i.type == "VULNERABILITY"); + public int bugIssues => issues.Count(i => i.type == "BUG"); + public int codeSmells => issues.Count(i => i.type == "CODE_SMELL"); + public List errors { get; set; } + public List issues { get; set; } + public List components { get; set; } + public List facets { get; set; } + public List rules { get; set; } + public List users { get; set; } +} + +#endregion + +#region WebServices + +public class WSActionParam +{ + public string key { get; set; } + public string description { get; set; } + public bool required { get; set; } + public bool @internal { get; set; } + public object exampleValue { get; set; } + public string defaultValue { get; set; } + public List possibleValues { get; set; } + public string deprecatedKey { get; set; } + public string deprecatedKeySince { get; set; } + public int? maximumValue { get; set; } + public string since { get; set; } + public string deprecatedSince { get; set; } + public int? minimumLength { get; set; } + public int? maxValuesAllowed { get; set; } + public int? maximumLength { get; set; } +} + +public class WSAction +{ + public string key { get; set; } + public string description { get; set; } + public string since { get; set; } + public bool @internal { get; set; } + public bool post { get; set; } + public bool hasResponseExample { get; set; } + public List changlog { get; set; } + public List Params { get; set; } + public string deprecatedSince { get; set; } +} + +public class WebService +{ + public string path { get; set; } + public string description { get; set; } + public List actions { get; set; } + public string since { get; set; } +} + +public class WebServices +{ + public List webServices { get; set; } +} + +#endregion \ No newline at end of file diff --git a/SonarQube API/Test the math.linq b/SonarQube API/Test the math.linq new file mode 100644 index 0000000..7bdb10c --- /dev/null +++ b/SonarQube API/Test the math.linq @@ -0,0 +1,30 @@ + + +public enum Severity +{ + Info = 1, + Minor = 2, + Major = 5, + Critical = 7, + Blocker = 10 +} + +void Main() +{ + Score(Severity.Critical, 5, 18).Dump(); + ScoreAlt(Severity.Critical, 5, 18).Dump(); +} + +// Define other methods and classes here + +public int Score(Severity severity, int debt, int items = 1) +{ + $"Math.Max(1, {debt} / 10 * {(int)severity}) * {items} items".Dump(); + return Math.Max(1, debt / 10 * (int)severity) * items; +} + +public int ScoreAlt(Severity severity, int debt, int items = 1) +{ + $"Math.Max(1, {debt} * {(int)severity} / 10) * {items} items".Dump(); + return Math.Max(1, debt * (int)severity / 10) * items; +} diff --git a/Split text by a phrase.linq b/Split text by a phrase.linq new file mode 100644 index 0000000..97a04c1 --- /dev/null +++ b/Split text by a phrase.linq @@ -0,0 +1,77 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var text = @"SELECT * +FROM cci.RunSavingHistory AS rsh +ORDER BY rsh.DateCreated DESC +GO +DELETE FROM cci.RunSavingHistory +"; + +var temp = System.IO.Path.GetTempFileName(); +File.WriteAllText(temp, text); +var input = File.ReadAllLines(temp); +var grp = 0; +input.Select(r => +{ + if (r.Equals("go", StringComparison.CurrentCultureIgnoreCase)) + { + r = ""; + return new {grp = grp++, r}; + } + else + { + return new {grp, r}; + } +}).GroupBy(r => r.grp, (x, lines) => string.Join(" ", lines.Select(l => l.r).Where(l => !string.IsNullOrEmpty(l)))).Dump(); diff --git a/StarterSet API/Standard Definition Mapping Standards.linq b/StarterSet API/Standard Definition Mapping Standards.linq new file mode 100644 index 0000000..5d9ec4f --- /dev/null +++ b/StarterSet API/Standard Definition Mapping Standards.linq @@ -0,0 +1,23 @@ + + + db640701-a1c5-4177-9f03-5152d093ffa7 + true + D0011-sql-01.sdt.local + jazz tst StrataSphere 20200612.1 + true + + Newtonsoft.Json + Newtonsoft.Json.Linq + + +var definitions = (from sdm in StandardDefinitionMappings select sdm).ToList(); +//definitions +//.OrderBy(d => d.StandardDefinitionType) +//.ThenBy(d => $"{JObject.Parse(d.MappingMemberValue)["mappings"][0]["text"]}") +//.Select(x => new { x.StandardDefinitionGUID, x.StandardDefinitionType, x.MappingMemberValue }).Dump(nameof(definitions)); +var inserts = definitions +.OrderBy(d => d.StandardDefinitionType) +.ThenBy(d => $"{JObject.Parse(d.MappingMemberValue)["mappings"][0]["text"]}") +.Aggregate("INSERT INTO dbo.StandardDefinitionMapping ( StandardDefinitionGUID, StandardDefinitionType, MappingMemberValue )\r\nVALUES", + (x, y) => $"{x}\r\n\t('{y.StandardDefinitionGUID}', N'{y.StandardDefinitionType}', N'{y.MappingMemberValue}'),"); +inserts.TrimEnd(',').Dump(nameof(inserts)); diff --git a/StarterSet API/Starter Set API Definitions Search.linq b/StarterSet API/Starter Set API Definitions Search.linq new file mode 100644 index 0000000..b887ca5 --- /dev/null +++ b/StarterSet API/Starter Set API Definitions Search.linq @@ -0,0 +1,318 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + jazz tst Riverside Health System 20190930.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + + +private string BaseUrl = "https://api-dev.sdt.local/StrataSphere.Web.API.Service/api/v1/"; +private IList _mappedDefinitions; + +void Main() +{ + RestClient client = new RestClient(); + var definitions = GetList(client, "Definitions"); + var standardDefinitionMappings = from def in StandardDefinitionMappings + select new + { + def.MappingId, + def.StandardDefinitionGUID, + def.StandardDefinitionType, + MappingMemberValue = JsonConvert.DeserializeObject(def.MappingMemberValue) + }; + var guidDefinitionDictionary = standardDefinitionMappings.ToDictionary(u => u.StandardDefinitionGUID); + var foundDefinitions = definitions.Where(p => guidDefinitionDictionary.ContainsKey(p.Id)); + _mappedDefinitions = (from d in foundDefinitions + join m in StandardDefinitionMappings on d.Id equals m.StandardDefinitionGUID + select new StrataSphereMappedDefinition(d, m.MappingMemberValue)).ToList(); + + var pathAlias = "HIERALIAS"; + var sqlTableAlias = "viewDimMetri"; + var attributeID = new[] { "Cardiomyopathy" }.ToList(); + StrataSphereMappedValue find; + attributeID.ForEach(id => + { + find = MapToStrataSphere("[Case Type Family MSDRG]", "[Case Type Family MSDRG].[Case Type Family]", + new List { $"{id}" }); + find.Dump($"StrataSphereMappedValue: {id}"); + }); +} + +// Define other methods and classes here +public StrataSphereMappedValue MapToStrataSphere(string dimensionId, string attributeId, IList valuesToMap) +{ + var mdx = new Regex(@"^(\[.+\]\.)+\[.+\]$"); + var clientValues = valuesToMap.Select(valueToMap => mdx.IsMatch(valueToMap) + ? AnalysisServicesUtils.GetMeasureIDFromMDXName(valueToMap) + : valueToMap).ToList(); + return FindMappedValue(dimensionId, attributeId, clientValues); +} + +public static class AnalysisServicesUtils +{ + public static string GetMeasureIDFromMDXName(string aMemberMDXName) + { + return aMemberMDXName; + } +} + +protected StrataSphereMappedValue FindMappedValue(string dimensionId, string attributeId, List valuesToMap) +{ + var definitions = _mappedDefinitions + .Where(d => d.DimensionId.Equals(dimensionId, StringComparison.CurrentCultureIgnoreCase) + && d.AttributeId.Equals(attributeId, StringComparison.CurrentCultureIgnoreCase)).ToList(); + var mappings = definitions.Where(p => p.MappedValues != null && p.MappedValues.mappings.Any()).SelectMany(p => p.MappedValues.mappings); + mappings.Dump(); + var mappedDefinition = definitions + .SingleOrDefault(p => p.MappedValues != null + && (!p.MappedValues.mappings.Any() || + p.MappedValues.mappings.SelectMany(m => m.attributeValues + .Select(a => a.ToString())) + .OrderBy(v => v).SequenceEqual(valuesToMap.OrderBy(v => v), StringComparer.CurrentCultureIgnoreCase))) ?? + definitions + .SingleOrDefault(p => p.MappedValues != null + && (!p.MappedValues.mappings.Any() || + p.MappedValues.mappings + .Select(m => m.name) + .OrderBy(v => v).SequenceEqual(valuesToMap.OrderBy(v => v), StringComparer.CurrentCultureIgnoreCase))) ?? + definitions + .SingleOrDefault(p => p.MappedValues != null + && (!p.MappedValues.mappings.Any() || + p.MappedValues.mappings + .Select(m => m.text) + .OrderBy(v => v).SequenceEqual(valuesToMap.OrderBy(v => v), StringComparer.CurrentCultureIgnoreCase))) ?? + definitions + .SingleOrDefault(p => p.MappedValues != null + && (!p.MappedValues.mappings.Any() || + p.MappedValues.mappings + .Select(m => m.id) + .OrderBy(v => v).SequenceEqual(valuesToMap.OrderBy(v => v), StringComparer.CurrentCultureIgnoreCase))) ?? + definitions + .SingleOrDefault(p => p.MappedValues != null + && (!p.MappedValues.mappings.Any() || + p.MappedValues.mappings + .SelectMany(m => m.hierarchyPaths) + .OrderBy(v => v).SequenceEqual(valuesToMap.OrderBy(v => v), StringComparer.CurrentCultureIgnoreCase))) ?? + definitions.FirstOrDefault(); + + return mappedDefinition != null + ? new StrataSphereMappedValue(valuesToMap, mappedDefinition.StrataSphereDefinitionGuid) + : new StrataSphereMappedValue(valuesToMap); +} + +public struct StrataSphereMappedValue +{ + public IList ClientValues { get; set; } + + public Guid? StrataSphereDefinitionGuid { get; set; } + + public StrataSphereMappedValue(IList clientValues) + { + ClientValues = clientValues; + StrataSphereDefinitionGuid = null; + } + + public StrataSphereMappedValue(IList clientValues, Guid definitionGuid) + { + ClientValues = clientValues; + StrataSphereDefinitionGuid = definitionGuid; + } + + public bool IsMapped => StrataSphereDefinitionGuid.HasValue; +} + +public class StrataSphereMappedDefinition +{ + public StrataSphereMappedDefinition(DefinitionDto definitionDto, string mappedValues) + { + StrataSphereDefinitionGuid = definitionDto.Id; + HierarchyGuid = definitionDto.HierarchyGuid; + DimensionGuid = definitionDto.DimensionGuid; + AttributeGuid = definitionDto.AttributeGuid; + HierarchyId = definitionDto.HierarchyId; + DimensionId = definitionDto.DimensionId; + AttributeId = definitionDto.AttributeId; + MappedValues = JsonConvert.DeserializeObject(mappedValues); + } + + public Guid StrataSphereDefinitionGuid { get; } + public Guid HierarchyGuid { get; } + public Guid DimensionGuid { get; } + public Guid AttributeGuid { get; } + public string HierarchyId { get; } + public string DimensionId { get; } + public string AttributeId { get; } + public StrataSphereMappingValues MappedValues { get; } +} + +public class StrataSphereMappingValues +{ + public string HierarchyGUID { get; set; } + public string DimensionGUID { get; set; } + public List values { get; set; } + public List mappings { get; set; } + public List hierarchyPaths { get; set; } + + public StrataSphereMappingValues() + { + mappings = new List(); + } +} + +public class MappingValue +{ + public string id { get; set; } + public string displayHierarchyName { get; set; } + public string text { get; set; } + public string name { get; set; } + public List attributeValues { get; set; } + public List hierarchyPaths { get; set; } + + public MappingValue() + { + attributeValues = new List(); + hierarchyPaths = new List(); + } +} + +public class ApiBaseDto +{ + /// + /// API Item Id Guid in StrataSphere + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid Id { get; set; } + + /// + /// When the API item was uploaded to StrataSphere + /// + public DateTime DateCreated { get; set; } + + /// + /// When the API item was last updated in StrataSphere + /// + public DateTime DateLastModified { get; set; } + +} + +public class DefinitionDto : ApiBaseDto +{ + + /// + /// The name of the definition + /// + /// TOP 10 DRGs BY SERVICE LINE + public string Name { get; set; } + + /// + /// A short description of the definition's content + /// + /// Top 10 DRGs by Service Line filtered per service line rollup + public string Description { get; set; } = ""; + + /// + /// The Guid of the Definition's hierarchy in a GM database + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid HierarchyGuid { get; set; } + + /// + /// The Guid of the Definition's dimension in a GM database + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid DimensionGuid { get; set; } + + /// + /// The Guid of the Definition's attribute in a GM database + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid AttributeGuid { get; set; } + + /// + /// The string of the Definition's hierarchy friendly name + /// + /// PatientTypeRollupID + public string HierarchyId { get; set; } + + /// + /// The string of the Definition's dimension Id + /// + /// [Patient Encounter] + public string DimensionId { get; set; } + + /// + /// The string of the Definition's attribute Id + /// + /// [Patient Encounter].[Service Line Strata Decision] + public string AttributeId { get; set; } + +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content); +} \ No newline at end of file diff --git a/StarterSet API/Starter Set API Definitions.linq b/StarterSet API/Starter Set API Definitions.linq new file mode 100644 index 0000000..4f59613 --- /dev/null +++ b/StarterSet API/Starter Set API Definitions.linq @@ -0,0 +1,134 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + StrataSphere + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + System.Dynamic + + +private string BaseUrl = "https://api-prod.sdt.local/starterset-api/api/v1/"; //"https://starterset-api.dev.k8s.sdt.local/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + client.BaseUrl = new Uri(BaseUrl.Replace("/api/v1/", "/health")); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + client.Execute(request).Content.Dump("health"); + + var definitions = GetList(client, "Definitions"); + definitions? + .OrderBy(d => d.Name).ThenBy(d => d.AttributeId) + .Dump(nameof(definitions)); + var mdx = GetList(client, "MdxScoreToCube"); + mdx? + .OrderBy(d => d.ScoreDimensionName).ThenBy(d => d.CubeDimensionName) + .Dump(nameof(mdx)); +} + +// Define other methods and classes here + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +public class DefinitionDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public Guid HierarchyGuid { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string HierarchyId { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + + public DefinitionDto() + { + } +} \ No newline at end of file diff --git a/StarterSet API/Starter Set API MdxScoreToCube.linq b/StarterSet API/Starter Set API MdxScoreToCube.linq new file mode 100644 index 0000000..14bf140 --- /dev/null +++ b/StarterSet API/Starter Set API MdxScoreToCube.linq @@ -0,0 +1,138 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + System.Dynamic + + +private string BaseUrl = "https://starterset-api.dev.k8s.sdt.local/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + var mdxScoreToCubes = GetList(client, "MdxScoreToCube"); + mdxScoreToCubes + .Where(stc => stc.ScoreDimensionName == "MR Metrics") + //.Where(d => d.DimensionGuid.ToString().Equals("A1823417-0B73-9950-D44C-2F3A9B9DDB92", StringComparison.CurrentCultureIgnoreCase)) + //.OrderBy(d => d.DimensionId) + .Dump(nameof(mdxScoreToCubes)); +} + +// Define other methods and classes here + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +public class MdxScoreToCubeDto +{ + public Guid Id { get; set; } + public string OrgPin { get; set; } + public Guid DatabaseGuid { get; set; } + public string ScoreDimensionName { get; set; } + public string ScoreHierarchyName { get; set; } + public string CubeDimensionName { get; set; } + public string CubeHierarchyName { get; set; } + public MdxMemberIdTypes MdxMemberIdType {get;set;} + public MdxForamtTypes MdxFormatType {get;set;} + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + + public MdxScoreToCubeDto() + { + } +} + +public enum MdxMemberIdTypes +{ + Attribute, + Name, + Text, + Id, + HierarchyPath +} + +public enum MdxForamtTypes +{ + None, + MDX, + Hierarchy, + MDXMemberId, + Raw +} \ No newline at end of file diff --git a/StarterSet API/Starter Set API Reports.linq b/StarterSet API/Starter Set API Reports.linq new file mode 100644 index 0000000..6fc9788 --- /dev/null +++ b/StarterSet API/Starter Set API Reports.linq @@ -0,0 +1,872 @@ + + + db640701-a1c5-4177-9f03-5152d093ffa7 + true + D0011-sql-01.sdt.local + jazz tst StrataSphere 20191104.1 + true + + Newtonsoft.Json + RestSharp + RestSharp + Newtonsoft.Json.Converters + Newtonsoft.Json + System.Dynamic + + +private string BaseUrl = @"https://localhost:44325/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + var reports = GetList(client, "Reports"); + reports.Dump(); +} + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +void other() +{ + StandardDefinitionMappings.Select(sdm => new + { + sdm.MappingId, + sdm.StandardDefinitionGUID, + sdm.StandardDefinitionType, + MappingMemberValue = JsonConvert.DeserializeObject(sdm.MappingMemberValue) + }).Dump("StandardDefinitionMappings"); + + REReports.Join(REDSCubeReportParameters, + r => r.ReportGUID, + p => p.ReportGUID, + (r, p) => new ReportInfo(p.ParameterXML) + { + Report = r.Name, + DimensionID = p.DimensionID, + AttributeID = p.AttributeID + }).Dump("Cube Reports"); + + REReports.Join(REClientReportParameters, + r => r.ReportGUID, + p => p.ReportGUID, + (r, p) => new ReportInfo(p.ParameterXML) + { + Report = r.Name, + DimensionID = p.DimensionID, + AttributeID = p.AttributeID + }).Dump("Client Reports"); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +void stuff(RestClient client) +{ + client.BaseUrl = new Uri(BaseUrl + "Definitions"); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var definitions = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definitions.Where(d => d.DimensionGuid == new Guid("6EF6B1F7-A50C-4198-8866-140BB82E2DDA")).Dump("Definitions"); + + client.BaseUrl = new Uri(BaseUrl + "MDXScoreToCube"); + var mdx = JsonConvert.DeserializeObject>(client.Execute(request).Content); + mdx.Dump("MDX"); + + client.BaseUrl = new Uri(BaseUrl + "Reports"); + var reports = JsonConvert.DeserializeObject>(client.Execute(request).Content); + reports.Dump("Reports"); + + var reportSetupUrl = new Uri(BaseUrl + "Reports/{0}/Setup"); + reports.Where(r => r.Id == new Guid("a4a12e21-954b-4889-d5c8-08d71f2ff590")).ToList().ForEach(r => + { + client.BaseUrl = new Uri(BaseUrl + $"Reports/{r.Id}"); + var rpt = JsonConvert.DeserializeObject(client.Execute(request).Content); + rpt.DefinitionIds.ForEach(d => + { + client.BaseUrl = new Uri(BaseUrl + $"Defintions/{d}"); + var definition = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definition.Dump($"Report {r.Name} Definition {d}"); + }); + }); + +} + +// Define other methods and classes here + +public class ReportInfo +{ + public string Report { get; set; } + public string DimensionID { get; set; } + public string AttributeID { get; set; } + public string ParameterXML { get; set; } + + internal XmlDocument doc; + public string Parameter { get; set; } + public ReportInfo(string parameterXML) + { + ParameterXML = parameterXML; + var parameterXml = ParameterXML = $"{ParameterXML}" + .RemoveAllNamespacesAsString() + .Replace("string>", "valueId>") + .Replace("", "") + .Replace("<_", "<").Replace("( + JsonConvert.SerializeXmlNode(doc.SelectSingleNode("root") + ) + ) + , + Newtonsoft.Json.Formatting.Indented); + } +} + +public class StrataSphereMappingValues +{ + public string HierarchyGUID { get; set; } + public string DimensionGUID { get; set; } + public List values { get; set; } + public List mappings { get; set; } + public List hierarchyPaths { get; set; } + + public StrataSphereMappingValues() + { + mappings = new List(); + } +} + +public class MappingValue +{ + public string id { get; set; } + public string displayHierarchyName { get; set; } + public string text { get; set; } + public string name { get; set; } + public List attributeValues { get; set; } + public List hierarchyPaths { get; set; } + + public MappingValue() + { + attributeValues = new List(); + hierarchyPaths = new List(); + } +} + +public enum eStrataSphereItemCategory +{ + Report, + Dashboard +} + +public enum StrataSphereReportEnum +{ + Report, + DSCubeReport, + SQLReport, + ClientReport +} + +public class ReportDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string Author { get; set; } + public eStrataSphereItemCategory Category => eStrataSphereItemCategory.Report; + public string Tagline => + $"Report | {Module} | {DateCreated.ToString("MMM-dd-YYYY")} | {DownloadCount} downloads"; + + public StrataSphereReportEnum ReportType { get; set; } + public string Module { get; set; } + public string MinJazzVersion { get; set; } + public string MaxJazzVersion { get; set; } + public string ReportSetupJson { get; set; } + public List DefinitionIds { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + public int DownloadCount { get; set; } + + public ReportDto() + { + ReportSetupJson = "{}"; + DefinitionIds = new List(); + } +} + +public class DefinitionDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public Guid HierarchyGuid { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string HierarchyId { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } +} + +public enum MDXMemberIDTypeEnum +{ + Attribute, + Name, + Text, + Id, + HierarchyPath +} + +public enum MDXFormatTypeEnum +{ + None, + MDX, + Hierarchy, + MDXMemberId +} + +public class MDXScoreToCubeDto +{ + public string OrgPin { get; set; } + public Guid DatabaseGuid { get; set; } + public string ScoreDimensionName { get; set; } + public string ScoreHierarchyName { get; set; } + public string CubeDimensionName { get; set; } + public string CubeHierarchyName { get; set; } + public MDXMemberIDTypeEnum MDXMemberIDType { get; set; } + public MDXFormatTypeEnum MDXFormatType { get; set; } +} + +public class ValueIDArray +{ + public List valueId { get; set; } +} + +public class DSCubeSearchCondition +{ + public string FilterOp { get; set; } + public string SearchType { get; set; } + public string Value2 { get; set; } + public string Value { get; set; } + public ValueIDArray ValueIDArray { get; set; } +} + +public class SearchConditions +{ + public DSCubeSearchCondition DSCubeSearchCondition { get; set; } +} + +public class DSCubeSearchParameterValue +{ + public string ParameterGUID { get; set; } + public string ParameterValueGUID { get; set; } + public SearchConditions SearchConditions { get; set; } +} + +public class Root +{ + public DSCubeSearchParameterValue DSCubeSearchParameterValue { get; set; } +} + +public class RootObject +{ + public Root root { get; set; } +} + +#region StrataSphereAdHocReportSetup + +public interface IStrataSphereAdHocReportSectionItem +{ + string Name { get; set; } + bool IsOnChartXAxis { get; set; } + bool IsOnChartYAxis { get; set; } +} + +internal class StrataSphereAdHocReportAttribute : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportAttribute() + { + + } + + public string AttributeId { get; set; } + public string DimensionId { get; set; } + public int Index { get; set; } + public string Name { get; set; } + public IList FilterMembers { get; set; } + public int VisibilityStatusValue { get; set; } + public bool ShowSubtotal { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); + //public List Parameters { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportCalculation : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportCalculation() + { + } + public string Name { get; set; } + public string CalcType { get; set; } + public int DisplayOrder { get; set; } + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + public string CalculationJson { get; set; } + public string CssClass { get; set; } + public bool IsAttributeMember { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportConditionalFormat +{ + public StrataSphereAdHocReportConditionalFormat() + { + + } + public string Comment { get; set; } + public int DisplayOrder { get; set; } + public ReportTupleInfo ColumnTupleInfo { get; set; } + public string CssClass { get; set; } + public string ValueToCompareAsString { get; set; } + public int OperatorValue { get; set; } +} + +internal class StrataSphereAdHocReportConfig +{ + public string Title { get; set; } + public string Description { get; set; } + public string[] Colors { get; set; } + public AxisSetting AxisSettings { get; set; } + public string XType { get; set; } + public bool YAxisMultiSelect { get; set; } + public Guid XAxisSectionItemGuid { get; set; } + public List YAxisSectionItemGuids { get; set; } = new List(); + + public StrataSphereAdHocReportConfig(BaseConfig source) + { + if (source == null) return; + Title = source.Title; + Description = source.Description; + Colors = source.Colors; + AxisSettings = source.AxisSettings; + XType = source.XType; + YAxisMultiSelect = source.YAxisMultiSelect; + } + + public BaseConfig GetChartConfig() + { + var chartConfig = default(BaseConfig); + /* + // Try decoding the xType by the name first + var asm = typeof(AreaConfig).Assembly; + var type = asm.GetType($"{asm.GetName().Name}.Reporting.ChartConfigs.{XType}"); + if (type != null) + { + chartConfig = (BaseConfig)Activator.CreateInstance(type); + } + else // if that failed then use the hard coded selector, this is an issue if new types are supported + { + switch (XType) + { + case "AreaConfig": + chartConfig = new AreaConfig(); + break; + case "BarConfig": + chartConfig = new BarConfig(); + break; + case "BubbleConfig": + chartConfig = new BubbleConfig(); + break; + case "ColumnConfig": + chartConfig = new ColumnConfig(); + break; + case "ComboColumnAndLineConfig": + chartConfig = new ComboColumnAndLineConfig(); + break; + case "ComboColumnAndLineWithSecondaryAxisConfig": + chartConfig = new ComboColumnAndLineWithSecondaryAxisConfig(); + break; + case "DonutConfig": + chartConfig = new DonutConfig(); + break; + case "LineConfig": + chartConfig = new LineConfig(); + break; + case "PieConfig": + chartConfig = new PieConfig(); + break; + case "ScatterConfig": + chartConfig = new ScatterConfig(); + break; + case "SplineConfig": + chartConfig = new SplineConfig(); + break; + case "StackedBarConfig": + chartConfig = new StackedBarConfig(); + break; + case "StackedBarPercentConfig": + chartConfig = new StackedBarPercentConfig(); + break; + case "StackedColumnConfig": + chartConfig = new StackedColumnConfig(); + break; + case "StackedColumnPercentConfig": + chartConfig = new StackedColumnPercentConfig(); + break; + } + } + */ + if (chartConfig == null) return chartConfig; + chartConfig.Title = Title; + chartConfig.Description = Description; + chartConfig.Colors = Colors; + chartConfig.AxisSettings = AxisSettings; + // if (chartConfig is XYConfig xyConfig) + // { + // xyConfig.XAxisSectionItemGuid = XAxisSectionItemGuid; + // xyConfig.YAxisSectionItemGuids.AddRange(YAxisSectionItemGuids); + // } + return chartConfig; + } + +} + +internal class StrataSphereAdHocReportDataSource +{ + public StrataSphereAdHocReportDataSource() + { + + } + public Guid DataSourceGuid { get; set; } + public string Name { get; set; } + public int DataSourceType { get; set; } +} + +internal class StrataSphereAdHocReportMeasure : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportMeasure() + { + + } + public string MeasureId { get; set; } + public string Name { get; set; } + public int Index { get; set; } + + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportSection +{ + public StrataSphereAdHocReportSection() + { + + } + public string Name { get; set; } + public bool IsOnColumn { get; set; } + public int DisplayOrder { get; set; } + public bool IsTimeRelative { get; set; } + + public bool IsFinancialReportSectionHidable { get; set; } + public bool IsMergingRepeatHeader { get; set; } + public bool IsSpaceAbove { get; set; } + public bool IsHidden { get; set; } + + public string DisplayLabel { get; set; } + public bool ShowSectionLabel { get; set; } + public bool ShowGrandTotal { get; set; } + public bool IsAutoNameFilter { get; set; } + public bool ShowMargin { get; set; } + + public List Attributes { get; set; } = new List(); + + public List Measures { get; set; } = new List(); + + public List Calculations { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportSetup +{ + public string Style { get; set; } + + public StrataSphereAdHocReportSortArgs SortArgs { get; set; } + + public List DataSources { get; set; } = new List(); + + public StrataSphereAdHocReportConfig ChartConfig { get; set; } = null; + + public List Sections { get; set; } = new List(); + + public List Parameters { get; set; } = new List(); + + public List ServiceLines { get; set; } = + new List(); + +} + +public class StrataSphereAdHocReportSortArgs +{ + public StrataSphereAdHocReportTupleInfo TupleInfo { get; set; } + public bool IsAscending { get; set; } + public int SortCount { get; set; } + public int Top { get; set; } + public bool IsTopPercent { get; set; } + public bool IsIncludeAllOthers { get; set; } + + public StrataSphereAdHocReportSortArgs() + { + TupleInfo = new StrataSphereAdHocReportTupleInfo(); + } +} + +public class StrataSphereAdHocReportTupleInfo +{ + public Dictionary PartialRowTuple { get; set; } + public Dictionary PartialColTuple { get; set; } + public string MainMeasureName { get; private set; } + public string RowMeasureName { get; set; } + public string ColMeasureName { get; set; } + public Guid ColMeasureGUID { get; set; } + public string FormatString { get; set; } + public int rowIndex { get; set; } + public int colIndex { get; set; } + public Guid ColumnSectionGUID { get; set; } + public IAdHocReportSectionMeasure MainMeasure { get; set; } + + public StrataSphereAdHocReportTupleInfo() + { + PartialRowTuple = new Dictionary(); + PartialColTuple = new Dictionary(); + ColumnSectionGUID = Guid.Empty; + ColMeasureGUID = Guid.Empty; + } + + public StrataSphereAdHocReportTupleInfo(ReportTupleInfo tupleInfo) + : this() + { + if (tupleInfo == null) return; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + //MainMeasure = tupleInfo.MainMeasure; + MainMeasureName = tupleInfo.MainMeasureName; + RowMeasureName = tupleInfo.RowMeasureName; + ColMeasureName = tupleInfo.ColMeasureName; + ColMeasureGUID = tupleInfo.ColMeasureGUID; + FormatString = tupleInfo.FormatString; + rowIndex = tupleInfo.rowIndex; + colIndex = tupleInfo.colIndex; + ColumnSectionGUID = tupleInfo.ColumnSectionGUID; + } + + public static implicit operator ReportTupleInfo(StrataSphereAdHocReportTupleInfo tupleInfo) + { + if (tupleInfo == null) return null; + var result = new ReportTupleInfo + { + PartialRowTuple = new Dictionary(), + PartialColTuple = new Dictionary(), + MainMeasure = tupleInfo.MainMeasure?.CopyMeasure(), + RowMeasureName = tupleInfo.RowMeasureName, + ColMeasureName = tupleInfo.ColMeasureName, + ColMeasureGUID = tupleInfo.ColMeasureGUID, + FormatString = tupleInfo.FormatString, + rowIndex = tupleInfo.rowIndex, + colIndex = tupleInfo.colIndex, + ColumnSectionGUID = tupleInfo.ColumnSectionGUID + }; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => result.PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => result.PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + return result; + } +} + +internal interface IStrataReportParameter +{ + string DimensionId { get; set; } + string AttributeId { get; set; } +} + +internal abstract class StrataSphereAdHocReportParameter : IStrataReportParameter +{ + protected StrataSphereAdHocReportParameter() + { + } + + public string Name { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public string MeasureId { get; set; } + public int DisplayOrder { get; set; } + public bool IsUserEditable { get; set; } + + public bool IsAttributeParameter => string.IsNullOrWhiteSpace(MeasureId); + +} + +public class StrataSphereAdHocScoreDimensionInfo +{ + public Guid DimensionGUID { get; set; } + public string FriendlyName { get; set; } + public string GlobalID { get; set; } + public string AttributeId { get; set; } + public string MDXMemberID { get; set; } + public bool IsRollup { get; set; } + internal Regex ServiceLineRegex = new Regex(@"^Service Line (\d)$", RegexOptions.IgnoreCase); + + // internal string MDXMemberName => AnalysisServicesUtils.GetHierarchyMDXName("Patient Encounter", + // ServiceLineRegex.IsMatch(FriendlyName) && IsRollup + // ? $"{ServiceLineRegex.Replace(FriendlyName, "Service Line Rollup ${1}")}" + // : $"{FriendlyName}{(IsRollup ? " Rollup" : "")}"); + + internal string Name => $"Patient Encounter - {FriendlyName}{(IsRollup ? " Rollup" : "")}"; + + internal StrataSphereAdHocScoreDimensionInfo() + { + MDXMemberID = string.Empty; + IsRollup = false; + } +} + +#endregion + + +#region Other Stuff + +public interface IAdHocReportSectionMeasure //: IAdHocReportSectionItem +{ + string ColumnName { get; set; } + string DisplayFormat { get; } + string CSSClass { get; } + List LinkedSectionGUIDs { get; } + void Hide(); + string MeasureID { get; } + + bool IsPartial { get; } + bool IsAttributeMember { get; } + + eAggregateFunction AggregationTypeEnum { get; } + IAdHocReportSectionMeasure CopyMeasure(); +} + + +public interface ITGuid +{ + Guid Value { get; set; } + bool IsEmpty { get; set; } +} + +public enum eClientReportSectionItemType +{ + Attribute = 0, + Hierarchy = 1, + Measure = 2, + Calculation = 3 +} + +public enum eReportDrilldownStatus +{ + None = 0, + Drilldown = 1, + Drillup = 2 +} + +public enum eClientReportVisibilityStatus +{ + Hidden = 0, + CompletelyVisible = 1, + PartiallyVisible = 2 +} + +public enum eAggregateFunction +{ + Sum = 0, + Count = 1, + Avg = 2, + Min = 3, + Max = 4, + None = 5 +} + + +public interface IAdHocReportSectionAttribute //: IAdHocReportSectionItem +{ + ITGuid AttributeGUIDTyped { get; } + string DimensionID { get; } + string AttributeID { get; } + bool ShowSubtotal { get; set; } + + SortOrder SortOrder { get; } + eClientReportVisibilityStatus VisibilityStatus { get; set; } + eReportDrilldownStatus DrilldownStatus { get; set; } + + string FilterMemberCSV { get; set; } + List FilterMembers { get; set; } + List FilterMembersVisible { get; } +} + +public class ReportTupleInfo +{ + public ReportTupleInfo() + { + this.PartialRowTuple = new Dictionary(); + this.PartialColTuple = new Dictionary(); + } + + private Dictionary _Tuple; + public Dictionary Tuple + { + get + { + return _Tuple; + } + set { _Tuple = value; } + } + + public Dictionary PartialRowTuple { get; set; } + + public Dictionary PartialColTuple { get; set; } + + public string MainMeasureName { get; private set; } + + private IAdHocReportSectionMeasure _MainMeasure; + public IAdHocReportSectionMeasure MainMeasure + { + get { return _MainMeasure; } + set + { + _MainMeasure = value; + MainMeasureName = (value == null) ? string.Empty : value.ColumnName; + } + } + + public string RowMeasureName { get; set; } + + public string ColMeasureName { get; set; } + + public Guid ColMeasureGUID { get; set; } + + public string FormatString { get; set; } + + public int rowIndex { get; set; } + + public int colIndex { get; set; } + + public Guid ColumnSectionGUID { get; set; } + +} + +public class AxisSetting +{ + public string XAxisLabel { get; set; } + public string YAxisLabel { get; set; } + public double? YAxisLowerBound { get; set; } + public double? YAxisUpperBound { get; set; } + public double? YAxisTickInterval { get; set; } + public double? YAxisPlotLineValue { get; set; } + public bool ShowDataLabel { get; set; } + + public override bool Equals(object obj) + { + var config = (AxisSetting)obj; + + if (config == null) return false; + if (config.XAxisLabel != this.XAxisLabel) return false; + if (config.YAxisLabel != this.YAxisLabel) return false; + if (config.YAxisLowerBound != this.YAxisLowerBound) return false; + if (config.YAxisUpperBound != this.YAxisUpperBound) return false; + if (config.YAxisTickInterval != this.YAxisTickInterval) return false; + if (config.YAxisPlotLineValue != this.YAxisPlotLineValue) return false; + if (config.ShowDataLabel != this.ShowDataLabel) return false; + + return true; + } + +} + +public abstract class BaseConfig +{ + public abstract DataTable GetData(object report); + + public abstract string Name { get; } + + public string Title { get; set; } + + public string Description { get; set; } + + public string[] Colors { get; set; } + + public AxisSetting AxisSettings { get; set; } + + public virtual string IconName { get { return ""; } } + public virtual string XType { get { return ""; } } + public virtual string SectionName { get { return ""; } } + public virtual int ColumnNumber { get { return -1; } } + public virtual int RowNumber { get { return -1; } } + public virtual bool YAxisMultiSelect { get { return true; } } + + protected BaseConfig() + { + this.Colors = new string[] { }; + this.AxisSettings = new AxisSetting(); + } + + public override bool Equals(object obj) + { + var config = (BaseConfig)obj; + + if (config == null) return false; + if (config.Title != Title || config.Description != Description) return false; + if (config.Colors.Length != Colors.Length) return false; + if (config.Colors.Any(p => !Colors.Contains(p))) return false; + if (!config.AxisSettings.Equals(this.AxisSettings)) return false; + if (config.GetType().Name != this.GetType().Name) return false; + + return true; + } + +} +#endregion \ No newline at end of file diff --git a/StarterSet API/Starter Set API Validate Endpoint.linq b/StarterSet API/Starter Set API Validate Endpoint.linq new file mode 100644 index 0000000..8e154cf --- /dev/null +++ b/StarterSet API/Starter Set API Validate Endpoint.linq @@ -0,0 +1,96 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + + +private string BaseUrl = @"https://api-prod.sdt.local/starterset-api"; +private string Resource = @"Reports/Populate"; + +void Main() +{ + var client = new RestClient(); + BaseUrl += "/api/v1"; + client.BaseUrl = new Uri(BaseUrl); + DumpEndpoint(client, "prod"); + Resource = @"Reports/Test"; + DumpEndpoint(client, "Test"); + Resource = @"Reports/a281733b-30d8-4d51-2148-08d799ffe4e4/Setup"; + DumpEndpoint(client, Resource); + + Resource = @"Reports/Populate"; + var environments = new[] { "dev", "qa", "training" }.ToList(); + environments.ForEach(env => + { + DumpEnv(client, env); + }); +} + +void DumpEnv(RestClient client, string env) +{ + BaseUrl = $@"https://starterset-api.{env}.k8s.sdt.local"; + BaseUrl += "/api/v1"; + client.BaseUrl = new Uri(BaseUrl); + DumpEndpoint(client, env); +} + +void DumpEndpoint(RestClient client, string env) +{ + var request = new RestRequest(); + request.Method = Method.GET; + request.Resource = Resource; + var response = client.Execute(request); + response.Content.Dump(env); +} + +// Define other methods and classes here \ No newline at end of file diff --git a/StarterSet API/Starter Set API With Report Setup.linq b/StarterSet API/Starter Set API With Report Setup.linq new file mode 100644 index 0000000..80a0e0c --- /dev/null +++ b/StarterSet API/Starter Set API With Report Setup.linq @@ -0,0 +1,908 @@ + + DataGrids + Newtonsoft.Json + RestSharp + RestSharp + Newtonsoft.Json.Converters + Newtonsoft.Json + System.Dynamic + + +private string BaseUrl = +//"https://starterset-api.dev.k8s.sdt.local/api/v1/"; +"https://localhost:44325/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + var reports = GetList(client, "Reports"); + + var rpts = reports + .Where(r => r.Name.StartsWith("TL Fiscal Month Test")) + .OrderBy(r => r.Name) + .ToList() + .Select(rpt => new { rpt.Id, rpt.Name, setup = GetList(client, $"Reports\\{rpt.Id}\\Setup") }) + //.Where(x => ((IDictionary)x.setup).ContainsKey("ServiceLines")) + ; + rpts.Dump(nameof(rpts),6); + + var definitions = GetList(client, "Definitions") + .Where(dd => dd.DimensionId == "e18e27ea-52ec-4793-9209-c6259c78474a" + || dd.DimensionId == "Fiscan Month"); + definitions.Dump(); + + /* + var setups = rpts.Select(r => r.setup); + setups.Dump(nameof(setups)); + var serviceLines = setups.Where(x => ((IDictionary)x).ContainsKey("ServiceLines")) + .SelectMany(s => ((List)s.ServiceLines) + .Select(x => x)); + serviceLines.Dump(nameof(serviceLines)); + + var dataSources = setups.SelectMany(s => ((List)s.DataSources) + .Select(x => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(x)))) + .GroupBy(ds => ds.DataSourceGuid, (g, d) => d.First()); + dataSources.Dump(nameof(dataSources)); + // var globalParameters = setups.SelectMany(s => ((List)s.Parameters) + // .Select(x => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(x)))); + // globalParameters.Dump(nameof(globalParameters)); + var sections = setups.SelectMany(s => ((List)s.Sections) + .Select(x => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(x)))); + var attributes = sections.SelectMany(s => s.Attributes) + .Select(x => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(x))); + attributes.Dump(nameof(attributes)); + var attrParms = attributes.SelectMany(a => a.Parameters); + attrParms.Dump(nameof(attrParms)); + var calculations = sections.SelectMany(s => s.Calculations) + .Select(x => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(x))); + calculations.Dump(nameof(calculations)); + */ +} + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +//void other() +//{ +// StandardDefinitionMappings.Select(sdm => new +// { +// sdm.MappingId, +// sdm.StandardDefinitionGUID, +// sdm.StandardDefinitionType, +// MappingMemberValue = JsonConvert.DeserializeObject(sdm.MappingMemberValue) +// }).Dump("StandardDefinitionMappings"); +// +// REReports.Join(REDSCubeReportParameters, +// r => r.ReportGUID, +// p => p.ReportGUID, +// (r, p) => new ReportInfo(p.ParameterXML) +// { +// Report = r.Name, +// DimensionID = p.DimensionID, +// AttributeID = p.AttributeID +// }).Dump("Cube Reports"); +// +// REReports.Join(REClientReportParameters, +// r => r.ReportGUID, +// p => p.ReportGUID, +// (r, p) => new ReportInfo(p.ParameterXML) +// { +// Report = r.Name, +// DimensionID = p.DimensionID, +// AttributeID = p.AttributeID +// }).Dump("Client Reports"); +//} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content, + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Error.Message.Dump(); + args.ErrorContext.Handled = true; + } + }); +} + +void stuff(RestClient client) +{ + client.BaseUrl = new Uri(BaseUrl + "Definitions"); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var definitions = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definitions.Where(d => d.DimensionGuid == new Guid("6EF6B1F7-A50C-4198-8866-140BB82E2DDA")).Dump("Definitions"); + + client.BaseUrl = new Uri(BaseUrl + "MDXScoreToCube"); + var mdx = JsonConvert.DeserializeObject>(client.Execute(request).Content); + mdx.Dump("MDX"); + + client.BaseUrl = new Uri(BaseUrl + "Reports"); + var reports = JsonConvert.DeserializeObject>(client.Execute(request).Content); + reports.Dump("Reports"); + + var reportSetupUrl = new Uri(BaseUrl + "Reports/{0}/Setup"); + reports.Where(r => r.Id == new Guid("a4a12e21-954b-4889-d5c8-08d71f2ff590")).ToList().ForEach(r => + { + client.BaseUrl = new Uri(BaseUrl + $"Reports/{r.Id}"); + var rpt = JsonConvert.DeserializeObject(client.Execute(request).Content); + rpt.DefinitionIds.ForEach(d => + { + client.BaseUrl = new Uri(BaseUrl + $"Defintions/{d}"); + var definition = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definition.Dump($"Report {r.Name} Definition {d}"); + }); + }); + +} + +// Define other methods and classes here + +public class ReportInfo +{ + public string Report { get; set; } + public string DimensionID { get; set; } + public string AttributeID { get; set; } + public string ParameterXML { get; set; } + + internal XmlDocument doc; + public string Parameter { get; set; } + public ReportInfo(string parameterXML) + { + ParameterXML = parameterXML; + var parameterXml = ParameterXML = $"{ParameterXML}" + .RemoveAllNamespacesAsString() + .Replace("string>", "valueId>") + .Replace("", "") + .Replace("<_", "<").Replace("( + JsonConvert.SerializeXmlNode(doc.SelectSingleNode("root") + ) + ) + , + Newtonsoft.Json.Formatting.Indented); + } +} + +public class StrataSphereMappingValues +{ + public string HierarchyGUID { get; set; } + public string DimensionGUID { get; set; } + public List values { get; set; } + public List mappings { get; set; } + public List hierarchyPaths { get; set; } + + public StrataSphereMappingValues() + { + mappings = new List(); + } +} + +public class MappingValue +{ + public string id { get; set; } + public string displayHierarchyName { get; set; } + public string text { get; set; } + public string name { get; set; } + public List attributeValues { get; set; } + public List hierarchyPaths { get; set; } + + public MappingValue() + { + attributeValues = new List(); + hierarchyPaths = new List(); + } +} + +public enum eStrataSphereItemCategory +{ + Report, + Dashboard +} + +public enum StrataSphereReportEnum +{ + Report, + DSCubeReport, + SQLReport, + ClientReport +} + +public class ReportDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string Author { get; set; } + public eStrataSphereItemCategory Category => eStrataSphereItemCategory.Report; + public string Tagline => + $"Report | {Module} | {DateCreated.ToString("MMM-dd-YYYY")} | {DownloadCount} downloads"; + + public StrataSphereReportEnum ReportType { get; set; } + public string Module { get; set; } + public string MinJazzVersion { get; set; } + public string MaxJazzVersion { get; set; } + public string ReportSetupJson { get; set; } + public List DefinitionIds { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + public int DownloadCount { get; set; } + + public ReportDto() + { + ReportSetupJson = "{}"; + DefinitionIds = new List(); + } +} + +public class DefinitionDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public Guid HierarchyGuid { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string HierarchyId { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } +} + +public enum MDXMemberIDTypeEnum +{ + Attribute, + Name, + Text, + Id, + HierarchyPath +} + +public enum MDXFormatTypeEnum +{ + None, + MDX, + Hierarchy, + MDXMemberId +} + +public class MDXScoreToCubeDto +{ + public string OrgPin { get; set; } + public Guid DatabaseGuid { get; set; } + public string ScoreDimensionName { get; set; } + public string ScoreHierarchyName { get; set; } + public string CubeDimensionName { get; set; } + public string CubeHierarchyName { get; set; } + public MDXMemberIDTypeEnum MDXMemberIDType { get; set; } + public MDXFormatTypeEnum MDXFormatType { get; set; } +} + +public class ValueIDArray +{ + public List valueId { get; set; } +} + +public class DSCubeSearchCondition +{ + public string FilterOp { get; set; } + public string SearchType { get; set; } + public string Value2 { get; set; } + public string Value { get; set; } + public ValueIDArray ValueIDArray { get; set; } +} + +public class SearchConditions +{ + public DSCubeSearchCondition DSCubeSearchCondition { get; set; } +} + +public class DSCubeSearchParameterValue +{ + public string ParameterGUID { get; set; } + public string ParameterValueGUID { get; set; } + public SearchConditions SearchConditions { get; set; } +} + +public class Root +{ + public DSCubeSearchParameterValue DSCubeSearchParameterValue { get; set; } +} + +public class RootObject +{ + public Root root { get; set; } +} + +#region StrataSphereAdHocReportSetup + +public interface IStrataSphereAdHocReportSectionItem +{ + string Name { get; set; } + bool IsOnChartXAxis { get; set; } + bool IsOnChartYAxis { get; set; } +} + +internal class StrataSphereAdHocReportAttribute : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportAttribute() + { + + } + + public string AttributeId { get; set; } + public string DimensionId { get; set; } + public int Index { get; set; } + public string Name { get; set; } + public IList FilterMembers { get; set; } + public int VisibilityStatusValue { get; set; } + public bool ShowSubtotal { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); + //public List Parameters { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportCalculation : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportCalculation() + { + } + public string Name { get; set; } + public string CalcType { get; set; } + public int DisplayOrder { get; set; } + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + public string CalculationJson { get; set; } + public string CssClass { get; set; } + public bool IsAttributeMember { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportConditionalFormat +{ + public StrataSphereAdHocReportConditionalFormat() + { + + } + public string Comment { get; set; } + public int DisplayOrder { get; set; } + public ReportTupleInfo ColumnTupleInfo { get; set; } + public string CssClass { get; set; } + public string ValueToCompareAsString { get; set; } + public int OperatorValue { get; set; } +} + +internal class StrataSphereAdHocReportConfig +{ + public string Title { get; set; } + public string Description { get; set; } + public string[] Colors { get; set; } + public AxisSetting AxisSettings { get; set; } + public string XType { get; set; } + public bool YAxisMultiSelect { get; set; } + public Guid XAxisSectionItemGuid { get; set; } + public List YAxisSectionItemGuids { get; set; } = new List(); + + public StrataSphereAdHocReportConfig(BaseConfig source) + { + if (source == null) return; + Title = source.Title; + Description = source.Description; + Colors = source.Colors; + AxisSettings = source.AxisSettings; + XType = source.XType; + YAxisMultiSelect = source.YAxisMultiSelect; + } + + public BaseConfig GetChartConfig() + { + var chartConfig = default(BaseConfig); + /* + // Try decoding the xType by the name first + var asm = typeof(AreaConfig).Assembly; + var type = asm.GetType($"{asm.GetName().Name}.Reporting.ChartConfigs.{XType}"); + if (type != null) + { + chartConfig = (BaseConfig)Activator.CreateInstance(type); + } + else // if that failed then use the hard coded selector, this is an issue if new types are supported + { + switch (XType) + { + case "AreaConfig": + chartConfig = new AreaConfig(); + break; + case "BarConfig": + chartConfig = new BarConfig(); + break; + case "BubbleConfig": + chartConfig = new BubbleConfig(); + break; + case "ColumnConfig": + chartConfig = new ColumnConfig(); + break; + case "ComboColumnAndLineConfig": + chartConfig = new ComboColumnAndLineConfig(); + break; + case "ComboColumnAndLineWithSecondaryAxisConfig": + chartConfig = new ComboColumnAndLineWithSecondaryAxisConfig(); + break; + case "DonutConfig": + chartConfig = new DonutConfig(); + break; + case "LineConfig": + chartConfig = new LineConfig(); + break; + case "PieConfig": + chartConfig = new PieConfig(); + break; + case "ScatterConfig": + chartConfig = new ScatterConfig(); + break; + case "SplineConfig": + chartConfig = new SplineConfig(); + break; + case "StackedBarConfig": + chartConfig = new StackedBarConfig(); + break; + case "StackedBarPercentConfig": + chartConfig = new StackedBarPercentConfig(); + break; + case "StackedColumnConfig": + chartConfig = new StackedColumnConfig(); + break; + case "StackedColumnPercentConfig": + chartConfig = new StackedColumnPercentConfig(); + break; + } + } + */ + if (chartConfig == null) return chartConfig; + chartConfig.Title = Title; + chartConfig.Description = Description; + chartConfig.Colors = Colors; + chartConfig.AxisSettings = AxisSettings; + // if (chartConfig is XYConfig xyConfig) + // { + // xyConfig.XAxisSectionItemGuid = XAxisSectionItemGuid; + // xyConfig.YAxisSectionItemGuids.AddRange(YAxisSectionItemGuids); + // } + return chartConfig; + } + +} + +internal class StrataSphereAdHocReportDataSource +{ + public StrataSphereAdHocReportDataSource() + { + + } + public Guid DataSourceGuid { get; set; } + public string Name { get; set; } + public int DataSourceType { get; set; } +} + +internal class StrataSphereAdHocReportMeasure : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportMeasure() + { + + } + public string MeasureId { get; set; } + public string Name { get; set; } + public int Index { get; set; } + + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportSection +{ + public StrataSphereAdHocReportSection() + { + + } + public string Name { get; set; } + public bool IsOnColumn { get; set; } + public int DisplayOrder { get; set; } + public bool IsTimeRelative { get; set; } + + public bool IsFinancialReportSectionHidable { get; set; } + public bool IsMergingRepeatHeader { get; set; } + public bool IsSpaceAbove { get; set; } + public bool IsHidden { get; set; } + + public string DisplayLabel { get; set; } + public bool ShowSectionLabel { get; set; } + public bool ShowGrandTotal { get; set; } + public bool IsAutoNameFilter { get; set; } + public bool ShowMargin { get; set; } + + public List Attributes { get; set; } = new List(); + + public List Measures { get; set; } = new List(); + + public List Calculations { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportSetup +{ + public string Style { get; set; } + + public StrataSphereAdHocReportSortArgs SortArgs { get; set; } + + public List DataSources { get; set; } = new List(); + + public StrataSphereAdHocReportConfig ChartConfig { get; set; } = null; + + public List Sections { get; set; } = new List(); + + public List Parameters { get; set; } = new List(); + + public List ServiceLines { get; set; } = + new List(); + +} + +public class StrataSphereAdHocReportSortArgs +{ + public StrataSphereAdHocReportTupleInfo TupleInfo { get; set; } + public bool IsAscending { get; set; } + public int SortCount { get; set; } + public int Top { get; set; } + public bool IsTopPercent { get; set; } + public bool IsIncludeAllOthers { get; set; } + + public StrataSphereAdHocReportSortArgs() + { + TupleInfo = new StrataSphereAdHocReportTupleInfo(); + } +} + +public class StrataSphereAdHocReportTupleInfo +{ + public Dictionary PartialRowTuple { get; set; } + public Dictionary PartialColTuple { get; set; } + public string MainMeasureName { get; private set; } + public string RowMeasureName { get; set; } + public string ColMeasureName { get; set; } + public Guid ColMeasureGUID { get; set; } + public string FormatString { get; set; } + public int rowIndex { get; set; } + public int colIndex { get; set; } + public Guid ColumnSectionGUID { get; set; } + public IAdHocReportSectionMeasure MainMeasure { get; set; } + + public StrataSphereAdHocReportTupleInfo() + { + PartialRowTuple = new Dictionary(); + PartialColTuple = new Dictionary(); + ColumnSectionGUID = Guid.Empty; + ColMeasureGUID = Guid.Empty; + } + + public StrataSphereAdHocReportTupleInfo(ReportTupleInfo tupleInfo) + : this() + { + if (tupleInfo == null) return; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + //MainMeasure = tupleInfo.MainMeasure; + MainMeasureName = tupleInfo.MainMeasureName; + RowMeasureName = tupleInfo.RowMeasureName; + ColMeasureName = tupleInfo.ColMeasureName; + ColMeasureGUID = tupleInfo.ColMeasureGUID; + FormatString = tupleInfo.FormatString; + rowIndex = tupleInfo.rowIndex; + colIndex = tupleInfo.colIndex; + ColumnSectionGUID = tupleInfo.ColumnSectionGUID; + } + + public static implicit operator ReportTupleInfo(StrataSphereAdHocReportTupleInfo tupleInfo) + { + if (tupleInfo == null) return null; + var result = new ReportTupleInfo + { + PartialRowTuple = new Dictionary(), + PartialColTuple = new Dictionary(), + MainMeasure = tupleInfo.MainMeasure?.CopyMeasure(), + RowMeasureName = tupleInfo.RowMeasureName, + ColMeasureName = tupleInfo.ColMeasureName, + ColMeasureGUID = tupleInfo.ColMeasureGUID, + FormatString = tupleInfo.FormatString, + rowIndex = tupleInfo.rowIndex, + colIndex = tupleInfo.colIndex, + ColumnSectionGUID = tupleInfo.ColumnSectionGUID + }; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => result.PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => result.PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + return result; + } +} + +internal interface IStrataReportParameter +{ + string DimensionId { get; set; } + string AttributeId { get; set; } +} + +internal abstract class StrataSphereAdHocReportParameter : IStrataReportParameter +{ + protected StrataSphereAdHocReportParameter() + { + } + + public string Name { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public string MeasureId { get; set; } + public int DisplayOrder { get; set; } + public bool IsUserEditable { get; set; } + + public bool IsAttributeParameter => string.IsNullOrWhiteSpace(MeasureId); + +} + +public class StrataSphereAdHocScoreDimensionInfo +{ + public Guid DimensionGUID { get; set; } + public string FriendlyName { get; set; } + public string GlobalID { get; set; } + public string AttributeId { get; set; } + public string MDXMemberID { get; set; } + public bool IsRollup { get; set; } + internal Regex ServiceLineRegex = new Regex(@"^Service Line (\d)$", RegexOptions.IgnoreCase); + + // internal string MDXMemberName => AnalysisServicesUtils.GetHierarchyMDXName("Patient Encounter", + // ServiceLineRegex.IsMatch(FriendlyName) && IsRollup + // ? $"{ServiceLineRegex.Replace(FriendlyName, "Service Line Rollup ${1}")}" + // : $"{FriendlyName}{(IsRollup ? " Rollup" : "")}"); + + internal string Name => $"Patient Encounter - {FriendlyName}{(IsRollup ? " Rollup" : "")}"; + + internal StrataSphereAdHocScoreDimensionInfo() + { + MDXMemberID = string.Empty; + IsRollup = false; + } +} + +#endregion + + +#region Other Stuff + +public interface IAdHocReportSectionMeasure //: IAdHocReportSectionItem +{ + string ColumnName { get; set; } + string DisplayFormat { get; } + string CSSClass { get; } + List LinkedSectionGUIDs { get; } + void Hide(); + string MeasureID { get; } + + bool IsPartial { get; } + bool IsAttributeMember { get; } + + eAggregateFunction AggregationTypeEnum { get; } + IAdHocReportSectionMeasure CopyMeasure(); +} + + +public interface ITGuid +{ + Guid Value { get; set; } + bool IsEmpty { get; set; } +} + +public enum eClientReportSectionItemType +{ + Attribute = 0, + Hierarchy = 1, + Measure = 2, + Calculation = 3 +} + +public enum eReportDrilldownStatus +{ + None = 0, + Drilldown = 1, + Drillup = 2 +} + +public enum eClientReportVisibilityStatus +{ + Hidden = 0, + CompletelyVisible = 1, + PartiallyVisible = 2 +} + +public enum eAggregateFunction +{ + Sum = 0, + Count = 1, + Avg = 2, + Min = 3, + Max = 4, + None = 5 +} + + +public interface IAdHocReportSectionAttribute //: IAdHocReportSectionItem +{ + ITGuid AttributeGUIDTyped { get; } + string DimensionID { get; } + string AttributeID { get; } + bool ShowSubtotal { get; set; } + + SortOrder SortOrder { get; } + eClientReportVisibilityStatus VisibilityStatus { get; set; } + eReportDrilldownStatus DrilldownStatus { get; set; } + + string FilterMemberCSV { get; set; } + List FilterMembers { get; set; } + List FilterMembersVisible { get; } +} + +public class ReportTupleInfo +{ + public ReportTupleInfo() + { + this.PartialRowTuple = new Dictionary(); + this.PartialColTuple = new Dictionary(); + } + + private Dictionary _Tuple; + public Dictionary Tuple + { + get + { + return _Tuple; + } + set { _Tuple = value; } + } + + public Dictionary PartialRowTuple { get; set; } + + public Dictionary PartialColTuple { get; set; } + + public string MainMeasureName { get; private set; } + + private IAdHocReportSectionMeasure _MainMeasure; + public IAdHocReportSectionMeasure MainMeasure + { + get { return _MainMeasure; } + set + { + _MainMeasure = value; + MainMeasureName = (value == null) ? string.Empty : value.ColumnName; + } + } + + public string RowMeasureName { get; set; } + + public string ColMeasureName { get; set; } + + public Guid ColMeasureGUID { get; set; } + + public string FormatString { get; set; } + + public int rowIndex { get; set; } + + public int colIndex { get; set; } + + public Guid ColumnSectionGUID { get; set; } + +} + +public class AxisSetting +{ + public string XAxisLabel { get; set; } + public string YAxisLabel { get; set; } + public double? YAxisLowerBound { get; set; } + public double? YAxisUpperBound { get; set; } + public double? YAxisTickInterval { get; set; } + public double? YAxisPlotLineValue { get; set; } + public bool ShowDataLabel { get; set; } + + public override bool Equals(object obj) + { + var config = (AxisSetting)obj; + + if (config == null) return false; + if (config.XAxisLabel != this.XAxisLabel) return false; + if (config.YAxisLabel != this.YAxisLabel) return false; + if (config.YAxisLowerBound != this.YAxisLowerBound) return false; + if (config.YAxisUpperBound != this.YAxisUpperBound) return false; + if (config.YAxisTickInterval != this.YAxisTickInterval) return false; + if (config.YAxisPlotLineValue != this.YAxisPlotLineValue) return false; + if (config.ShowDataLabel != this.ShowDataLabel) return false; + + return true; + } + +} + +public abstract class BaseConfig +{ + public abstract DataTable GetData(object report); + + public abstract string Name { get; } + + public string Title { get; set; } + + public string Description { get; set; } + + public string[] Colors { get; set; } + + public AxisSetting AxisSettings { get; set; } + + public virtual string IconName { get { return ""; } } + public virtual string XType { get { return ""; } } + public virtual string SectionName { get { return ""; } } + public virtual int ColumnNumber { get { return -1; } } + public virtual int RowNumber { get { return -1; } } + public virtual bool YAxisMultiSelect { get { return true; } } + + protected BaseConfig() + { + this.Colors = new string[] { }; + this.AxisSettings = new AxisSetting(); + } + + public override bool Equals(object obj) + { + var config = (BaseConfig)obj; + + if (config == null) return false; + if (config.Title != Title || config.Description != Description) return false; + if (config.Colors.Length != Colors.Length) return false; + if (config.Colors.Any(p => !Colors.Contains(p))) return false; + if (!config.AxisSettings.Equals(this.AxisSettings)) return false; + if (config.GetType().Name != this.GetType().Name) return false; + + return true; + } + +} +#endregion \ No newline at end of file diff --git a/StarterSet API/Starter Set API test.linq b/StarterSet API/Starter Set API test.linq new file mode 100644 index 0000000..7c7422d --- /dev/null +++ b/StarterSet API/Starter Set API test.linq @@ -0,0 +1,1172 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod 20190708.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + + +private string BaseUrl = "https://api-prod.sdt.local/StrataSphere.Web.API.Service/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + var definitions = GetList(client, "Definitions"); + var hierarchies = (from scoreHierarchy in ViewScoreHierarchy select new { scoreHierarchy.HierarchyGUID, scoreHierarchy.FriendlyName, scoreHierarchy.DimensionGUID}).ToList() + .Where(sh => definitions.Select(d => d.HierarchyGuid).Contains(sh.HierarchyGUID)) + .GroupBy(sh => sh.HierarchyGUID, (grp, data) => new { HierarchyGUID = grp, DimensionGUID = data.First().DimensionGUID, FriendlyName = data.First().FriendlyName }); + //179B6541-2285-4196-4209-08D7469CC7F2 + definitions + //.Where(d => d.HierarchyId == "UB Revenue Code") + .Where(d => d.DimensionId == "Patient Encounter") + .OrderBy(d => d.DimensionId).ThenBy(d => d.AttributeId).ThenBy(d => d.Name).Dump("Definitions"); + hierarchies.Dump("Hierarchies"); + + var mdx = GetList(client, "MDXScoreToCube"); + mdx + .Where(m => m.OrgPin == "0430") + //.Where(m => m.CubeDimensionName.Contains("Patient")) + .OrderBy(m => m.ScoreHierarchyName) + .ThenBy(m => m.OrgPin).Dump("MDX Score to Cube"); +} + +void other() +{ + StandardDefinitionMappings.Select(sdm => new + { + sdm.MappingId, + sdm.StandardDefinitionGUID, + sdm.StandardDefinitionType, + MappingMemberValue = JsonConvert.DeserializeObject(sdm.MappingMemberValue) + }).Dump("StandardDefinitionMappings"); + + REReports.Join(REDSCubeReportParameters, + r => r.ReportGUID, + p => p.ReportGUID, + (r, p) => new ReportInfo(p.ParameterXML) + { + Report = r.Name, + DimensionID = p.DimensionID, + AttributeID = p.AttributeID + }).Dump("Cube Reports"); + + REReports.Join(REClientReportParameters, + r => r.ReportGUID, + p => p.ReportGUID, + (r, p) => new ReportInfo(p.ParameterXML) + { + Report = r.Name, + DimensionID = p.DimensionID, + AttributeID = p.AttributeID + }).Dump("Client Reports"); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content); +} + +void stuff(RestClient client) +{ + client.BaseUrl = new Uri(BaseUrl + "Definitions"); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var definitions = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definitions.Where(d => d.DimensionGuid == new Guid("6EF6B1F7-A50C-4198-8866-140BB82E2DDA")).Dump("Definitions"); + + client.BaseUrl = new Uri(BaseUrl + "MDXScoreToCube"); + var mdx = JsonConvert.DeserializeObject>(client.Execute(request).Content); + mdx.Dump("MDX"); + + client.BaseUrl = new Uri(BaseUrl + "Reports"); + var reports = JsonConvert.DeserializeObject>(client.Execute(request).Content); + reports.Dump("Reports"); + + var reportSetupUrl = new Uri(BaseUrl + "Reports/{0}/Setup"); + reports.Where(r => r.Id == new Guid("a4a12e21-954b-4889-d5c8-08d71f2ff590")).ToList().ForEach(r => + { + client.BaseUrl = new Uri(BaseUrl + $"Reports/{r.Id}"); + var rpt = JsonConvert.DeserializeObject(client.Execute(request).Content); + rpt.DefinitionIds.ForEach(d => + { + client.BaseUrl = new Uri(BaseUrl + $"Defintions/{d}"); + var definition = JsonConvert.DeserializeObject>(client.Execute(request).Content); + definition.Dump($"Report {r.Name} Definition {d}"); + }); + }); + +} + +// Define other methods and classes here + +public class ReportInfo +{ + public string Report { get; set; } + public string DimensionID { get; set; } + public string AttributeID { get; set; } + public string ParameterXML { get; set; } + + internal XmlDocument doc; + public string Parameter { get; set; } + public ReportInfo(string parameterXML) + { + ParameterXML = parameterXML; + var parameterXml = ParameterXML = $"{ParameterXML}" + .RemoveAllNamespacesAsString() + .Replace("string>", "valueId>") + .Replace("", "") + .Replace("<_", "<").Replace("( + JsonConvert.SerializeXmlNode(doc.SelectSingleNode("root") + ) + ) + , + Newtonsoft.Json.Formatting.Indented); + } +} + +public class StrataSphereMappingValues +{ + public string HierarchyGUID { get; set; } + public string DimensionGUID { get; set; } + public List values { get; set; } + public List mappings { get; set; } + public List hierarchyPaths { get; set; } + + public StrataSphereMappingValues() + { + mappings = new List(); + } +} + +public class MappingValue +{ + public string id { get; set; } + public string displayHierarchyName { get; set; } + public string text { get; set; } + public string name { get; set; } + public List attributeValues { get; set; } + public List hierarchyPaths { get; set; } + + public MappingValue() + { + attributeValues = new List(); + hierarchyPaths = new List(); + } +} + +public enum eStrataSphereItemCategory +{ + Report, + Dashboard +} + +public enum StrataSphereReportEnum +{ + Report, + DSCubeReport, + SQLReport, + ClientReport +} + +public class ReportDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string Author { get; set; } + public eStrataSphereItemCategory Category => eStrataSphereItemCategory.Report; + public string Tagline => + $"Report | {Module} | {DateCreated.ToString("MMM-dd-YYYY")} | {DownloadCount} downloads"; + + public StrataSphereReportEnum ReportType { get; set; } + public string Module { get; set; } + public string MinJazzVersion { get; set; } + public string MaxJazzVersion { get; set; } + public string ReportSetupJson { get; set; } + public List DefinitionIds { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + public int DownloadCount { get; set; } + + public ReportDto() + { + ReportSetupJson = "{}"; + DefinitionIds = new List(); + } +} + +public class DefinitionDto +{ + /// + /// Definition Guid in StrataSphere + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid Id { get; set; } + + /// + /// The name of the report + /// + /// TOP 10 DRGs BY SERVICE LINE + public string Name { get; set; } + + /// + /// A short description of the definition's content + /// + /// Top 10 DRGs by Service Line filtered per service line rollup + public string Description { get; set; } + + /// + /// The type of report (i.e. PatientPopulation, Metric) + /// + /// PatientPopulation + public Guid HierarchyGuid { get; set; } + + /// + /// The type of report (i.e. PatientPopulation, Metric) + /// + /// PatientPopulation + public Guid DimensionGuid { get; set; } + + /// + /// The Value of the Object Type + /// + /// All Cause 30 Day Readmits + public Guid AttributeGuid { get; set; } + + /// + /// The string of the Definition's dimension Id + /// + /// [Patient Encounter] + public string HierarchyId { get; set; } + + /// + /// The string of the Definition's dimension Id + /// + /// [Patient Encounter] + public string DimensionId { get; set; } + + /// + /// The string of the Definition's attribute Id + /// + /// [Patient Encounter].[Service Line Strata Decision] + public string AttributeId { get; set; } + + /// + /// When the definition was uploaded to StrataSphere + /// + public DateTime DateCreated { get; set; } + + /// + /// When the definition was last updated in StrataSphere + /// + public DateTime DateLastModified { get; set; } + +} + +public enum MDXMemberIDTypeEnum +{ + Attribute, + Name, + Text, + Id, + HierarchyPath +} + +public enum MDXFormatTypeEnum +{ + None, + MDX, + Hierarchy, + MDXMemberId +} + +public class MDXScoreToCubeDto +{ + /// + /// The orgpin or the item + /// + /// 0000 + public string OrgPin { get; set; } + + /// + /// The database guid of the item + /// + /// 00000000-0000-0000-0000-000000000000 + public Guid DatabaseGuid { get; set; } + + /// + /// The Score Dimension Name of the item + /// + /// Patient Type Rollup + public string ScoreDimensionName { get; set; } + + /// + /// The Score Hierarchy Name of the item + /// + /// Patient Type Rollup + public string ScoreHierarchyName { get; set; } + + /// + /// The Cube Dimension Name of the item + /// + /// Patient Type + public string CubeDimensionName { get; set; } + + /// + /// The Cube Hierarchy Name of the item + /// + /// Rollup + public string CubeHierarchyName { get; set; } + + /// + /// Indicates if the MDX should use the Attribute, Name, or Text value + /// + public MDXMemberIDTypeEnum MDXMemberIDType { get; set; } + + public MDXFormatTypeEnum MDXFormatType { get; set; } + +} + +public class ValueIDArray +{ + public List valueId { get; set; } +} + +public class DSCubeSearchCondition +{ + public string FilterOp { get; set; } + public string SearchType { get; set; } + public string Value2 { get; set; } + public string Value { get; set; } + public ValueIDArray ValueIDArray { get; set; } +} + +public class SearchConditions +{ + public DSCubeSearchCondition DSCubeSearchCondition { get; set; } +} + +public class DSCubeSearchParameterValue +{ + public string ParameterGUID { get; set; } + public string ParameterValueGUID { get; set; } + public SearchConditions SearchConditions { get; set; } +} + +public class Root +{ + public DSCubeSearchParameterValue DSCubeSearchParameterValue { get; set; } +} + +public class RootObject +{ + public Root root { get; set; } +} + +#region StrataSphereAdHocReportSetup + +public interface IStrataSphereAdHocReportSectionItem +{ + string Name { get; set; } + bool IsOnChartXAxis { get; set; } + bool IsOnChartYAxis { get; set; } +} + +internal class StrataSphereAdHocReportAttribute : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportAttribute() + { + + } + + public StrataSphereAdHocReportAttribute(IAdHocReportSectionAttribute attribute) + { + AttributeId = attribute.AttributeID; + DimensionId = attribute.DimensionID; + Index = attribute.DisplayOrder; + Name = attribute.Name; + FilterMembers = attribute.FilterMembers; + VisibilityStatusValue = (int)attribute.VisibilityStatus; + ShowSubtotal = attribute.ShowSubtotal; + } + + public string AttributeId { get; set; } + public string DimensionId { get; set; } + public int Index { get; set; } + public string Name { get; set; } + public IList FilterMembers { get; set; } + public int VisibilityStatusValue { get; set; } + public bool ShowSubtotal { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportCalculation : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportCalculation() + { + } + + public StrataSphereAdHocReportCalculation(IAdHocReportSectionCalculation calculation) + { + Name = calculation.Name; + CalcType = calculation.CalculationType.ID; + DisplayOrder = calculation.DisplayOrder; + ColumnWidth = calculation.ColumnWidth; + DisplayFormat = calculation.DisplayFormat; + CalculationJson = JsonConvert.SerializeObject(calculation.CalculationType); + CssClass = calculation.CSSClass; + IsAttributeMember = calculation.IsAttributeMember; + } + + public string Name { get; set; } + public string CalcType { get; set; } + public int DisplayOrder { get; set; } + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + public string CalculationJson { get; set; } + public string CssClass { get; set; } + public bool IsAttributeMember { get; set; } + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportConditionalFormat +{ + public StrataSphereAdHocReportConditionalFormat() + { + + } + + public StrataSphereAdHocReportConditionalFormat(IAdHocConditionalFormat conditionalFormat) + { + DisplayOrder = conditionalFormat.DisplayOrder; + Comment = conditionalFormat.Comment; + ColumnTupleInfo = conditionalFormat.ColumnTupleInfo; + } + + public string Comment { get; set; } + public int DisplayOrder { get; set; } + public ReportTupleInfo ColumnTupleInfo { get; set; } + public string CssClass { get; set; } + public string ValueToCompareAsString { get; set; } + public int OperatorValue { get; set; } +} + +internal class StrataSphereAdHocReportConfig +{ + public string Title { get; set; } + public string Description { get; set; } + public string[] Colors { get; set; } + public AxisSetting AxisSettings { get; set; } + public string XType { get; set; } + public bool YAxisMultiSelect { get; set; } + public Guid XAxisSectionItemGuid { get; set; } + public List YAxisSectionItemGuids { get; set; } = new List(); + + public StrataSphereAdHocReportConfig(BaseConfig source) + { + if (source == null) return; + Title = source.Title; + Description = source.Description; + Colors = source.Colors; + AxisSettings = source.AxisSettings; + XType = source.XType; + YAxisMultiSelect = source.YAxisMultiSelect; + } + + public BaseConfig GetChartConfig() + { + var chartConfig = default(BaseConfig); + // Try decoding the xType by the name first + var asm = typeof(AreaConfig).Assembly; + var type = asm.GetType($"{asm.GetName().Name}.Reporting.ChartConfigs.{XType}"); + if (type != null) + { + chartConfig = (BaseConfig)Activator.CreateInstance(type); + } + else // if that failed then use the hard coded selector, this is an issue if new types are supported + { + switch (XType) + { + case "AreaConfig": + chartConfig = new AreaConfig(); + break; + case "BarConfig": + chartConfig = new BarConfig(); + break; + case "BubbleConfig": + chartConfig = new BubbleConfig(); + break; + case "ColumnConfig": + chartConfig = new ColumnConfig(); + break; + case "ComboColumnAndLineConfig": + chartConfig = new ComboColumnAndLineConfig(); + break; + case "ComboColumnAndLineWithSecondaryAxisConfig": + chartConfig = new ComboColumnAndLineWithSecondaryAxisConfig(); + break; + case "DonutConfig": + chartConfig = new DonutConfig(); + break; + case "LineConfig": + chartConfig = new LineConfig(); + break; + case "PieConfig": + chartConfig = new PieConfig(); + break; + case "ScatterConfig": + chartConfig = new ScatterConfig(); + break; + case "SplineConfig": + chartConfig = new SplineConfig(); + break; + case "StackedBarConfig": + chartConfig = new StackedBarConfig(); + break; + case "StackedBarPercentConfig": + chartConfig = new StackedBarPercentConfig(); + break; + case "StackedColumnConfig": + chartConfig = new StackedColumnConfig(); + break; + case "StackedColumnPercentConfig": + chartConfig = new StackedColumnPercentConfig(); + break; + } + } + + if (chartConfig == null) return chartConfig; + chartConfig.Title = Title; + chartConfig.Description = Description; + chartConfig.Colors = Colors; + chartConfig.AxisSettings = AxisSettings; + if (chartConfig is XYConfig xyConfig) + { + xyConfig.XAxisSectionItemGuid = XAxisSectionItemGuid; + xyConfig.YAxisSectionItemGuids.AddRange(YAxisSectionItemGuids); + } + return chartConfig; + } + +} + +internal class StrataSphereAdHocReportDataSource +{ + public StrataSphereAdHocReportDataSource() + { + + } + + public StrataSphereAdHocReportDataSource(IDataSourceLink dataSourceLink) + { + DataSourceGuid = dataSourceLink.DataSourceGUID; + Name = dataSourceLink.DataSourceProvider.Name; + DataSourceType = (int)dataSourceLink.DataSourceProvider.DataSourceType; + } + + public Guid DataSourceGuid { get; set; } + public string Name { get; set; } + public int DataSourceType { get; set; } +} + +internal class StrataSphereAdHocReportMeasure : IStrataSphereAdHocReportSectionItem +{ + public StrataSphereAdHocReportMeasure() + { + + } + + public StrataSphereAdHocReportMeasure(IAdHocReportSectionMeasure measure) + { + MeasureId = measure.MeasureID; + Index = measure.DisplayOrder; + Name = measure.Name; + DisplayFormat = measure.DisplayFormat; + ColumnWidth = measure.ColumnWidth; + } + + public string MeasureId { get; set; } + public string Name { get; set; } + public int Index { get; set; } + + public string DisplayFormat { get; set; } + public int ColumnWidth { get; set; } + + public bool IsOnChartXAxis { get; set; } + public bool IsOnChartYAxis { get; set; } + + // section level filters + public List Parameters { get; set; } = new List(); + + public List ConditionalFormats { get; set; } = new List(); +} + +internal class StrataSphereAdHocReportSection +{ + public StrataSphereAdHocReportSection() + { + + } + + public StrataSphereAdHocReportSection(IReportDataGenerationSection section) + { + Name = section.Name; + DisplayOrder = section.DisplayOrder; + IsOnColumn = section.IsOnColumn; + IsTimeRelative = section.IsTimeRelative; + IsFinancialReportSectionHidable = section.IsFinancialReportSectionHidable; + IsMergingRepeatHeader = section.IsMergingRepeatHeader; + IsSpaceAbove = section.IsSpaceAbove; + IsHidden = section.IsHidden; + DisplayLabel = section.DisplayText; + ShowSectionLabel = section.ShowSectionLabel; + ShowGrandTotal = section.ShowGrandTotal; + ShowMargin = section.ShowMargin; + } + + public string Name { get; set; } + public bool IsOnColumn { get; set; } + public int DisplayOrder { get; set; } + public bool IsTimeRelative { get; set; } + + public bool IsFinancialReportSectionHidable { get; set; } + public bool IsMergingRepeatHeader { get; set; } + public bool IsSpaceAbove { get; set; } + public bool IsHidden { get; set; } + + public string DisplayLabel { get; set; } + public bool ShowSectionLabel { get; set; } + public bool ShowGrandTotal { get; set; } + public bool IsAutoNameFilter { get; set; } + public bool ShowMargin { get; set; } + + public List Attributes { get; set; } = new List(); + + public List Measures { get; set; } = new List(); + + public List Calculations { get; set; } = new List(); +} + + + +internal class StrataSphereAdHocReportSetup +{ + public string Style { get; set; } + + public StrataSphereAdHocReportSortArgs SortArgs { get; set; } + + public List DataSources { get; set; } = new List(); + + public StrataSphereAdHocReportConfig ChartConfig { get; set; } = null; + + public List Sections { get; set; } = new List(); + + public List Parameters { get; set; } = new List(); + + public List ServiceLines { get; set; } = + new List(); + +} + +public class StrataSphereAdHocReportSortArgs +{ + public StrataSphereAdHocReportTupleInfo TupleInfo { get; set; } + public bool IsAscending { get; set; } + public int SortCount { get; set; } + public int Top { get; set; } + public bool IsTopPercent { get; set; } + public bool IsIncludeAllOthers { get; set; } + + public StrataSphereAdHocReportSortArgs() + { + TupleInfo = new StrataSphereAdHocReportTupleInfo(); + } + + public StrataSphereAdHocReportSortArgs(IReportDataGenerationSetup reportSetup) + : this() + { + if (reportSetup.SortArgs == null) return; + TupleInfo = new StrataSphereAdHocReportTupleInfo(reportSetup); + IsAscending = reportSetup.SortArgs.IsAscending; + SortCount = reportSetup.SortArgs.SortCount; + Top = reportSetup.SortArgs.Top; + IsTopPercent = reportSetup.SortArgs.IsTopPercent; + IsIncludeAllOthers = reportSetup.SortArgs.IsIncludeAllOthers; + } + + public static implicit operator ReportSortArgs(StrataSphereAdHocReportSortArgs sortArgs) + { + var result = sortArgs.TupleInfo != null + ? new ReportSortArgs(sortArgs.TupleInfo) + : new ReportSortArgs(); + result.IsAscending = sortArgs.IsAscending; + result.SortCount = sortArgs.SortCount; + result.Top = sortArgs.Top; + result.IsTopPercent = sortArgs.IsTopPercent; + result.IsIncludeAllOthers = sortArgs.IsIncludeAllOthers; + return result; + } +} + +public class StrataSphereAdHocReportTupleInfo +{ + public Dictionary PartialRowTuple { get; set; } + public Dictionary PartialColTuple { get; set; } + public string MainMeasureName { get; private set; } + public string RowMeasureName { get; set; } + public string ColMeasureName { get; set; } + public Guid ColMeasureGUID { get; set; } + public string FormatString { get; set; } + public int rowIndex { get; set; } + public int colIndex { get; set; } + public Guid ColumnSectionGUID { get; set; } + public IAdHocReportSectionMeasure MainMeasure { get; set; } + + public StrataSphereAdHocReportTupleInfo() + { + PartialRowTuple = new Dictionary(); + PartialColTuple = new Dictionary(); + ColumnSectionGUID = Guid.Empty; + ColMeasureGUID = Guid.Empty; + } + + private IAdHocReportSectionMeasure _mainMeasure; + protected virtual IAdHocReportSectionMeasure InMemoryMeasure + { + get + { + if (_mainMeasure != null) return _mainMeasure; + _mainMeasure = new InMemoryReportMeasure + { + ColumnName = string.IsNullOrEmpty(RowMeasureName) + ? RowMeasureName + : ColMeasureName + }; + return _mainMeasure; + } + } + + public StrataSphereAdHocReportTupleInfo(ReportTupleInfo tupleInfo) + : this() + { + if (tupleInfo == null) return; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + //MainMeasure = tupleInfo.MainMeasure; + MainMeasureName = tupleInfo.MainMeasureName; + RowMeasureName = tupleInfo.RowMeasureName; + ColMeasureName = tupleInfo.ColMeasureName; + ColMeasureGUID = tupleInfo.ColMeasureGUID; + FormatString = tupleInfo.FormatString; + rowIndex = tupleInfo.rowIndex; + colIndex = tupleInfo.colIndex; + ColumnSectionGUID = tupleInfo.ColumnSectionGUID; + } + + public StrataSphereAdHocReportTupleInfo(IReportDataGenerationSetup reportSetup) + : this(reportSetup.SortArgs.TupleInfo) + { + if (reportSetup.SortArgs.TupleInfo?.MainMeasure == null) return; + switch (reportSetup) + { + case DSCubeReportSetup cubeReportSetup: + MainMeasure = cubeReportSetup.SortArgs.TupleInfo.MainMeasure as DSCubeReportSectionMeasure; + break; + case ClientReportSetup clientReportSetup: + MainMeasure = clientReportSetup.SortArgs.TupleInfo.MainMeasure as ClientReportSectionMeasure; + break; + default: + MainMeasure = InMemoryMeasure; + break; + } + switch (MainMeasure) + { + case DSCubeReportSectionMeasure cubeMeasure: + cubeMeasure.Re + portSetup = null; + break; + case ClientReportSectionMeasure clientMeasure: + clientMeasure.ReportSetup = null; + break; + } + } + + public static implicit operator ReportTupleInfo(StrataSphereAdHocReportTupleInfo tupleInfo) + { + if (tupleInfo == null) return null; + var result = new ReportTupleInfo + { + PartialRowTuple = new Dictionary(), + PartialColTuple = new Dictionary(), + MainMeasure = tupleInfo.MainMeasure?.CopyMeasure(), + RowMeasureName = tupleInfo.RowMeasureName, + ColMeasureName = tupleInfo.ColMeasureName, + ColMeasureGUID = tupleInfo.ColMeasureGUID, + FormatString = tupleInfo.FormatString, + rowIndex = tupleInfo.rowIndex, + colIndex = tupleInfo.colIndex, + ColumnSectionGUID = tupleInfo.ColumnSectionGUID + }; + tupleInfo.PartialRowTuple.Keys.ToList() + .ForEach(key => result.PartialRowTuple.Add(key, tupleInfo.PartialRowTuple[key])); + tupleInfo.PartialColTuple.Keys.ToList() + .ForEach(key => result.PartialColTuple.Add(key, tupleInfo.PartialColTuple[key])); + return result; + } +} +#endregion + +#region Other Stuff + +public interface IReportDataGenerationSection : IStrataTreeNode +{ + bool IsDeleted { get; } + IReportDataGenerationSetup ReportSetup { get; } + ITGuid ReportSectionGUIDTyped { get; } + Guid SectionGUID { get; } + string Name { get; } + + bool IsOnColumn { get; } + int DisplayOrder { get; } + bool IsTimeRelative { get; } + + bool IsFinancialReportSectionHidable { get; } + bool IsMergingRepeatHeader { get; } + bool IsSpaceAbove { get; } + + void AddAttribute(IAdHocReportSectionAttribute attr); + bool RemoveAttribute(IAdHocReportSectionAttribute attr); + void RemoveAttributeAt(int attrIndex); + + void AddMeasure(IAdHocReportSectionMeasure meas); + bool RemoveMeasure(IAdHocReportSectionMeasure meas); + void RemoveMeasureAt(int attrIndex); + + void AddCalculation(IAdHocReportSectionCalculation calc); + bool RemoveCalculation(IAdHocReportSectionCalculation calc); + void RemoveCalculationAt(int calcIndex); + + IEnumerable Calculations { get; } + IEnumerable Attributes { get; } + IEnumerable Measures { get; } + + IEnumerable GetAdditionalSelectColumns(); + + IEnumerable GetCostMeasureFilter(); + + IList GetValidVisibleAttributes(bool isDrillDown); + void RefreshVisibilityStatuses(IAdHocReportSectionAttribute drilledAttr, eReportDrilldownStatus ddStatus); + + List ChildMeasuresAndCalcs { get; } + List VisibleMeasuresAndCalcs { get; } + IAdHocReportSectionMeasure GetPrimaryMeasureForUseInCalculation(); + + List GetAllSectionItems { get; } + IEnumerable GetExtractAttributes(); + List GetAllSectionItemGUIDs(); + + bool HasParameters(); + void RefreshDrilldownStatuses(); + + void HidePartiallyVisibleItems(); + + #region " Rendering " + + bool IsHidden { get; } + bool ShowSectionLabel { get; } + + bool ShowGrandTotal { get; set; } + string GrandTotalDisplayTextOverride { get; } + string GrandTotalDisplayFormatOverride { get; } + bool ShowMargin { get; } + + string SectionLabelCSSClassName { get; } + + #endregion +} + +public class ReportTupleInfo +{ + public ReportTupleInfo() + { + this.PartialRowTuple = new Dictionary(); + this.PartialColTuple = new Dictionary(); + } + + [NonSerialized] + private IReportTupleFactory _TupleFactory; + public IReportTupleFactory TupleFactory + { + get { return _TupleFactory; } + set { _TupleFactory = value; } + } + + private Dictionary _Tuple; + public Dictionary Tuple + { + get + { + if (_Tuple == null) + { + RefreshTuple(); + } + return _Tuple; + } + set { _Tuple = value; } + } + + [DataMember] + public Dictionary PartialRowTuple { get; set; } + + [DataMember] + public Dictionary PartialColTuple { get; set; } + + [DataMember] + public string MainMeasureName { get; private set; } + + private IAdHocReportSectionMeasure _MainMeasure; + public IAdHocReportSectionMeasure MainMeasure + { + get { return _MainMeasure; } + set + { + _MainMeasure = value; + MainMeasureName = (value == null) ? string.Empty : value.ColumnName; + } + } + + [DataMember] + public string RowMeasureName { get; set; } + + [DataMember] + public string ColMeasureName { get; set; } + + [DataMember] + public Guid ColMeasureGUID { get; set; } + + [DataMember] + public string FormatString { get; set; } + + [DataMember] + public int rowIndex { get; set; } + + [DataMember] + public int colIndex { get; set; } + + [DataMember] + public Guid ColumnSectionGUID { get; set; } + + public Dictionary RefreshTuple() + { + _Tuple = new Dictionary(); + if (PartialRowTuple != null) + { + _Tuple.MergeUnsafe(PartialRowTuple); + } + if (PartialColTuple != null) + { + _Tuple.Merge(PartialColTuple); + } + return _Tuple; + } + + public ReportTupleInfo MakeCopy() + { + var copy = new ReportTupleInfo() + { + TupleFactory = this.TupleFactory, + PartialColTuple = new Dictionary(this.PartialColTuple), + PartialRowTuple = new Dictionary(this.PartialRowTuple), + MainMeasure = this.MainMeasure, + RowMeasureName = this.RowMeasureName, + ColMeasureName = this.ColMeasureName, + ColMeasureGUID = this.ColMeasureGUID, + ColumnSectionGUID = this.ColumnSectionGUID, + FormatString = this.FormatString, + rowIndex = this.rowIndex, + colIndex = this.colIndex + }; + return copy; + } + + public void MergeTuples(ReportTupleInfo tupleToMerge) + { + PartialColTuple = (Dictionary)PartialColTuple.MergeCopy(tupleToMerge.PartialColTuple); + PartialRowTuple = (Dictionary)PartialRowTuple.MergeCopy(tupleToMerge.PartialRowTuple); + RefreshTuple(); + } + + public override bool Equals(object obj) + { + if (!(obj is ReportTupleInfo)) + { + return false; + } + + var y = (ReportTupleInfo)obj; + + if (this.MainMeasure == null) + { + return false; + } + + if (!this.MainMeasure.ID.Equals(y.MainMeasure.ID)) + { + return false; + } + if (!this.Tuple.ValueEquals(y.Tuple)) + { + return false; + } + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + //not sure how else we can do GetHashCode without being super slow so we will need the base class decide + } +} + +public interface IAdHocReportSectionAttribute : IAdHocReportSectionItem +{ + ITGuid AttributeGUIDTyped { get; } + string DimensionID { get; } + string AttributeID { get; } + bool ShowSubtotal { get; set; } + + SortOrder SortOrder { get; } + eClientReportVisibilityStatus VisibilityStatus { get; set; } + eReportDrilldownStatus DrilldownStatus { get; set; } + + string FilterMemberCSV { get; set; } + List FilterMembers { get; set; } + List FilterMembersVisible { get; } +} + +public interface IAdHocReportSectionItem //: IDisplayOrder, IStrataTreeNode +{ + Guid ReportSectionGUID { get; } + Guid ReportSectionItemGUID { get; } + + string Name { get; set; } + string ColumnName { get; } + bool IsHidden { get; } + bool IsDeleted { get; } + + eClientReportSectionItemType ItemType { get; } + void SetID(Guid newGUID); + + int ColumnWidth { get; set; } + string DetailReportGUIDsCSV { get; } + Guid BeforeCopyGUID { get; set; } +} + +public interface ITGuid +{ + Guid Value { get; set; } + bool IsEmpty { get; set; } +} + +public enum eClientReportSectionItemType +{ + Attribute = 0, + Hierarchy = 1, + Measure = 2, + Calculation = 3 +} + +public enum eReportDrilldownStatus +{ + None = 0, + Drilldown = 1, + Drillup = 2 +} + +public enum eClientReportVisibilityStatus +{ + Hidden = 0, + CompletelyVisible = 1, + PartiallyVisible = 2 +} + +#endregion \ No newline at end of file diff --git a/StarterSet API/Starter Set API with Flurl test.linq b/StarterSet API/Starter Set API with Flurl test.linq new file mode 100644 index 0000000..5c0cef4 --- /dev/null +++ b/StarterSet API/Starter Set API with Flurl test.linq @@ -0,0 +1,107 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Flurl + Flurl.Http + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Flurl + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Threading.Tasks + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + Flurl.Http + + +private string baseUrl; + +void Main() +{ + baseUrl = "https://api-dev.sdt.local/StrataSphere.Web.API.Service//api/v1/"; + GetDefinitions().Dump(); + GetDefinitionsAsync().Dump(); +} + +// Define other methods and classes here +public async Task> GetDefinitionsAsync() +{ + return await GetTAsync("Definitions"); +} + +public async Task> GetTAsync(string pathSegment) +{ + var flurlRequest = baseUrl.AppendPathSegment(pathSegment).GetJsonAsync>(); + //flurlRequest.Wait(); + await flurlRequest; + while (!flurlRequest.IsCompleted) + { + if (flurlRequest.Exception != null) return new List(); + } + var result = flurlRequest.Result; + return result; +} + +public IEnumerable GetDefinitions() +{ + return Task.Run(async () => GetDefinitionsAsync().Result).Result; +} + +public class DefinitionDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public Guid DimensionGuid { get; set; } + public Guid AttributeGuid { get; set; } + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + +} + + diff --git a/StarterSet API/Starter Set Client StandardDefinitions.linq b/StarterSet API/Starter Set Client StandardDefinitions.linq new file mode 100644 index 0000000..8a93c36 --- /dev/null +++ b/StarterSet API/Starter Set Client StandardDefinitions.linq @@ -0,0 +1,72 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +Definitions +.OrderBy(d => d.ObjectType) +.ThenBy(d => d.Name) +.Dump(); \ No newline at end of file diff --git a/StarterSet API/Starter Set Missing Report Card Items for DatabaseGuid.linq b/StarterSet API/Starter Set Missing Report Card Items for DatabaseGuid.linq new file mode 100644 index 0000000..14b86b7 --- /dev/null +++ b/StarterSet API/Starter Set Missing Report Card Items for DatabaseGuid.linq @@ -0,0 +1,66 @@ + + + 463c2997-8a6a-4688-9575-6549e5215f7b + true + D0011-SQL-01.sdt.local + StrataSphere + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +from ri in ReportItems +join rci in ReportCardItems on ri.ReportCardItemId equals rci.Id +orderby ri.ReportId, rci.ReportCardItemType, rci.Name +where (!(from rcm in ReportCardMatches where rcm.ReportCardItemId == ri.ReportCardItemId && rcm.DatabaseGuid == Guid.Parse("9BC301F9-66C3-48AA-81E7-114F88A449EA") select rcm).Any()) +select new { ri.ReportId, rci.Id, rci.Name, rci.ReportCardItemType, rci.ReportType, rci.ReportCardItemDataJson } diff --git a/StarterSet API/Starter Set Test.linq b/StarterSet API/Starter Set Test.linq new file mode 100644 index 0000000..f063eba --- /dev/null +++ b/StarterSet API/Starter Set Test.linq @@ -0,0 +1,176 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + System.Dynamic + + +private string BaseUrl = "https://api-prod.sdt.local/StrataSphere.Web.API.Service/api/v1/"; + +void Main() +{ + RestClient client = new RestClient(); + var reports = GetList(client, "Reports"); + var setups = reports.ToList() + .Select(rpt => GetList(client, $"Reports\\{rpt.Id}\\Setup")); + var attributes = setups.SelectMany(s => (s.Sections as List).Select(x => (x.Attributes as List))); + //attributes.Dump(); + var results = attributes + .SelectMany(a => a.Select(x => new AttributeInfo + { + DimensionId = x.DimensionId, + AttributeId = x.AttributeId, + Name = x.Name, + Parameters = (x.Parameters as List) + .ConvertAll(p => new AttributeInfo + { + DimensionId = p.DimensionId, + AttributeId = p.AttributeId, + MeasureId = p.MeasureId, + DisplayOrder = p.DisplayOrder, + Name = p.Name + }).OrderBy(p => p.DisplayOrder) + })).GroupBy(x => x.ToString(), (grp, data) => data.First()) + .OrderBy(a => a.Name); + results.Dump(); +} + +public class AttributeInfo +{ + public string DimensionId { get; set; } + public string AttributeId { get; set; } + public string MeasureId { get; set; } + public long DisplayOrder { get; set; } = 0; + public string Name { get; set; } + public IEnumerable Parameters { get; set; } + + public override bool Equals(object obj) + { + var test = obj as AttributeInfo; + if (test == null) return false; + return test.Name == Name && test.DimensionId == DimensionId && test.AttributeId == AttributeId; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public override string ToString() + { + return $"{Name} {DimensionId} {AttributeId} {DisplayOrder} {(Parameters?.Aggregate("", (x, y) => $"{x} {y.ToString()}") ?? "")}"; + } +} + +dynamic GetList(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + var converter = new ExpandoObjectConverter(); + return JsonConvert.DeserializeObject(client.Execute(request).Content, converter); +} + +IEnumerable GetList(RestClient client, string something) +{ + return Get>(client, something); +} + +T Get(RestClient client, string something) +{ + client.BaseUrl = new Uri(BaseUrl + something); + RestRequest request = new RestRequest(); + request.Method = Method.GET; + return JsonConvert.DeserializeObject(client.Execute(request).Content); +} + +public enum eStrataSphereItemCategory +{ + Report, + Dashboard +} + +public enum StrataSphereReportEnum +{ + Report, + DSCubeReport, + SQLReport, + ClientReport +} + +public class ReportDto +{ + public Guid Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string Author { get; set; } + public eStrataSphereItemCategory Category => eStrataSphereItemCategory.Report; + public string Tagline => + $"Report | {Module} | {DateCreated.ToString("MMM-dd-YYYY")} | {DownloadCount} downloads"; + + public StrataSphereReportEnum ReportType { get; set; } + public string Module { get; set; } + public string MinJazzVersion { get; set; } + public string MaxJazzVersion { get; set; } + public string ReportSetupJson { get; set; } + public List DefinitionIds { get; set; } + public DateTime DateCreated { get; set; } + public DateTime DateLastModified { get; set; } + public int DownloadCount { get; set; } + + public ReportDto() + { + ReportSetupJson = "{}"; + DefinitionIds = new List(); + } +} diff --git a/StarterSet API/StarterSet DB Compare.linq b/StarterSet API/StarterSet DB Compare.linq new file mode 100644 index 0000000..6bb23d0 --- /dev/null +++ b/StarterSet API/StarterSet DB Compare.linq @@ -0,0 +1,239 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private string tableQuery = @"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ('stratasphere') +AND (CASE c.TABLE_SCHEMA +WHEN 'stratasphere' THEN 1 +ELSE + CASE WHEN c.TABLE_NAME IN ('DimCaseType', 'CaseTypeFamily', 'CaseTypeFamilyMapping', 'CaseTypeFamilyMappingAPRDRG', 'CaseTypeFamilyMappingICD10', 'CaseTypeFamilyMappingCPT', 'CaseTypeFamilyVersion') + THEN 1 ELSE 0 END END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; + +private List OrderByStatements; +private List ColumnsToBeExcluded; + +void Main() +{ + OrderByStatements = new List + { + new OrderByInformation{ + TableName = "cci.InitiativeWorkflowHistory", + OrderBy = "\r\nOrder By OBJ.FromStep, OBJ.ToStep" + }, + new OrderByInformation{ + TableName = "cci.VariationEncounterSavingInfo", + OrderBy = "\r\nOrder By OBJ.EncounterRecordNumber, OBJ.PhysicianID" + }, + new OrderByInformation{ + TableName = "stratasphere.MDXScoreToCube", + OrderBy = "\r\nOrder By OBJ.OrgPin, OBJ.ScoreDimensionName, ScoreHierarchyName" + } + }; + ColumnsToBeExcluded = new List { + new ColumnsToExclude{ + TableName = "stratasphere.MDXScoreToCube", + ColumnNames = new [] {"DateCreated", "DateLastModified"} + } + }; + var conn = new Tuple("D0011-SQL-01.sdt.local", "stratasphere"); + var q = GetQueries(conn); + + var connections = new ServerInstance[] { + new ServerInstance("D0011-SQL-01.sdt.local","stratasphere", q.Select(r => r.TableName).ToArray()), + new ServerInstance("E0001-SQL-11.sdt.local", "stratasphere", q.Select(r => r.TableName).ToArray() ) + }.ToList(); + var sql = string.Join("\r\n", q.Select(r => r.SqlSelect)); + var dataLegacy = GetData(connections[0], sql); + var dataUpdate = GetData(connections[1], sql); + + foreach (var dt in Enumerable.Range(0, dataLegacy.Tables.Count)) + { + var legacy = dataLegacy.Tables[dt].Rows; + var update = dataUpdate.Tables[dt].Rows; + var idxCount = legacy.Count; + var compare = new List>(); + foreach (var row in Enumerable.Range(0, idxCount)) + { + var r = legacy[row]; + if (row < update.Count) + { + var u = update[row]; + var rJson = JsonConvert.SerializeObject(r.ItemArray); + var uJson = JsonConvert.SerializeObject(u.ItemArray); + if (rJson != uJson) + { + compare.Add(new Tuple(r, u)); + } + } + else + { + compare.Add(new Tuple(r, null)); + } + } + if (compare.Any()) + { + compare.Dump(dataLegacy.Tables[dt].TableName, 2); + } + else + { + "No differences found in data".Dump(dataLegacy.Tables[dt].TableName); + } + } +} + +// Define other methods and classes here + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + public IEnumerable TableNames { get; set; } + public ServerInstance(string server, string database, string[] tableNames) + { + Server = server; + Database = database; + TableNames = tableNames; + } +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public string OrderBy { get; set; } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } +} + +public List GetQueries(Tuple connection) +{ + var server = connection.Item1; + var database = connection.Item2; + var sql = tableQuery; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var dataset = new DataTable(); + var adapter = new SqlDataAdapter(sql, conn); + adapter.Fill(dataset); + var items = dataset.AsEnumerable().Select(r => r).ToList().ConvertAll(r => r.ItemArray) + .Select(r => new InformationSchema { schema = (string)r[0], table = (string)r[1], column = (string)r[2], datatype = (string)r[3], isPrimaryKey = (bool)r[4] }) + .Where(r => !ColumnsToBeExcluded.SingleOrDefault(ctbe => ctbe.TableName == r.schemaTable)?.ColumnNames.Contains(r.column) ?? true) + .GroupBy(r => new { r.schema, r.table }, (t, c) => + new SqlInformation + { + TableName = $"{t.schema}.{t.table}", + SqlSelect = "Select\r\n" + c.Aggregate("", (x, y) => $"{x}, obj.{y.column}\r\n").Substring(1) + $" FROM {t.schema}.{t.table} OBJ" + + OrderByStatements.SingleOrDefault(obs => obs.TableName.Equals($"{t.schema}.{t.table}", StringComparison.CurrentCultureIgnoreCase))?.OrderBy ?? "" + + ";" + }) + .ToList(); + return items; + } +} + +public class SqlInformation +{ + public string TableName { get; set; } + public string SqlSelect { get; set; } +} + +public class InformationSchema +{ + public string schema { get; set; } + public string table { get; set; } + public string column { get; set; } + public string datatype { get; set; } + public bool isPrimaryKey { get; set; } + public string schemaTable => $"{schema}.{table}"; +} + +public DataSet GetData(ServerInstance serverInstance, string sql) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var dataset = new DataSet(); + var adapter = new SqlDataAdapter(sql, conn); + adapter.Fill(dataset); + var tableNames = serverInstance.TableNames; + var idx = 0; + foreach (var tableName in tableNames) + { + dataset.Tables[idx].TableName = tableName; + idx += 1; + } + return dataset; + } +} \ No newline at end of file diff --git a/StarterSet DB compare.linq b/StarterSet DB compare.linq new file mode 100644 index 0000000..6476985 --- /dev/null +++ b/StarterSet DB compare.linq @@ -0,0 +1,505 @@ + + + 690bdbda-0918-4699-b08c-addb41e49702 + true + E0001-sql-11.sdt.local + StrataSphere + true + + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Linq.Dynamic + + +// This link provides a good explanation of the Dynamic Query used in the DataTableJoins +// https://ecs.syr.edu/faculty/fawcett/handouts/CoreTechnologies/CSharp/samples/CSharpSamples/LinqSamples/DynamicQuery/Dynamic%20Expressions.html +// + +private List SchemasAndTablesToReview = new List(); + +#region Options + +public static int TopRows = 2000; //int.MaxValue; +public static bool ShowTableQuery = false; +public static bool ShowTableList = false; +public static int TableDumpDepth = int.MaxValue; //2; + +#endregion + +void Main() +{ + SchemasAndTablesToReview.AddRange(new[] + { + new TablesAndColumns("stratasphere", null), + }); + + var tables = GetTables().ToList(); + // Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + tables.ForEach(table => + { + switch (table.TableName) + { + case "Dashboard": + table.Init( + new[] { new OrderBy("Name"), new OrderBy("Module"), new OrderBy("MinJazzVersion") }, + new[] { "Id", "DateCreated", "DateLastModified" }, + new[] { "Name", "Module", "MinJazzVersion" } + ); + break; + case "DashboardCardItem": + table.Init( + new[] { new OrderBy("Name") }, + new[] { "ItemId", "DateCreated", "DateLastModified" }, + new[] { "Name", "DashboardCardItemType" } + ); + break; + case "Definition": + table.Init( + new[] { new OrderBy("Name"), new OrderBy("DimensionId"), new OrderBy("AttributeId") }, + new[] { "Id", "DateCreated", "DateLastModified" }, + new[] { "Name", "DimensionId", "AttributeId" } + ); + break; + case "Download": + table.Init( + new[] { new OrderBy("UserName"), new OrderBy("DownloadType") }, + new[] { "DownloadDateTime" }, + new[] { "UserName", "DownloadType" }, + null, + "OBJ.UserName <> 'System'" + ); + break; + case "MDXScoreToCube": + table.Init( + new[] { new OrderBy("OrgPin"), new OrderBy("ScoreDimensionName"), new OrderBy("ScoreHierarchyName") }, + new[] { "DateCreated", "DateLastModified" }, + new[] { "OrgPin", "ScoreDimensionName", "ScoreHierarchyName" } + ); + break; + case "Parameter": + table.Init( + new[] { new OrderBy("Name"), new OrderBy("ParameterType"), new OrderBy("DisplayOrder"), new OrderBy("DimensionName"), new OrderBy("AttributeName") }, + new[] { "DateCreated", "DateLastModified" }, + new[] { "Name", "ParameterType", "DimensionName", "AttributeName" }, + new[] { "ParameterJson" } + ); + break; + case "Report": + table.Init( + new[] { new OrderBy("Name"), new OrderBy("Module"), new OrderBy("MinJazzVersion") }, + new[] { "ItemId", "DownloadCount", "DateCreated", "DateLastModified" }, + new[] { "Name", "Module", "MinJazzVersion", "ReportType" }, + new[] { "ReportSetupJson" } + ); + break; + }; + }); + if (ShowTableList) tables.Dump(nameof(tables)); + var connections = new Connections + { + Legacy = new ServerInstance("E0001-SQL-11.sdt.local", "StrataSphere"), + Update = new ServerInstance("D0011-SQL-01.sdt.local", "StrataSphere") + // Legacy = new ServerInstance("D0011-SQL-01.sdt.local", "jazz tst Southern Illinois 20190918.1"), + // Update = new ServerInstance("D0011-SQL-01.sdt.local", "jazz tst Southern Illinois 20200331.1") + // Legacy = new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod 20190708.1"), + // Update = new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod") + }; + DoTheComparisons(connections, tables); +} + +// Define other methods and classes here + +#region Gather Table Information + +public string GetTableQuery() +{ + var tableSchemas = string.Join(", ", SchemasAndTablesToReview.Select(sattr => $"'{sattr.SchemaName}'")); + var tableList = string.Join("\r\n", SchemasAndTablesToReview.ConvertAll(sattr => + { + if (sattr.TableNames?.Any(cn => cn == "*") ?? true) + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' THEN 1"; + } + else + { + return $"WHEN c.TABLE_SCHEMA = '{sattr.SchemaName}' AND c.TABLE_NAME IN ({string.Join(", ", sattr.TableNames.Select(cn => $"'{cn}'"))}) THEN 1"; + } + })); + return $@"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ({tableSchemas}) +AND (CASE +{tableList} +ELSE 0 +END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; +} + +public IList
GetTables() +{ + var tableQuery = GetTableQuery(); + if (ShowTableQuery) tableQuery.Dump(nameof(tableQuery)); + return ExecuteQueryDynamic(tableQuery) + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_NAME }, + (g, d) => new Table(g.TABLE_SCHEMA, g.TABLE_NAME, + d.Select(y => new Column(y.COLUMN_NAME, y.DATA_TYPE, y.IsPrimaryKey)).ToList())) + .ToList(); +} + +public class Table +{ + public string SchemaName { get; set; } + public string TableName { get; set; } + public IList Columns { get; set; } = new List(); + public IList OrderBy { get; set; } = new List(); + public IList Exclude { get; set; } = new List(); + public IList KeyColumn { get; set; } = new List(); + public IList Json { get; set; } = new List(); + public string Where { get; set; } = ""; + internal string SchemaTable => $"{SchemaName}.{TableName}"; + public string SqlSelect => $"select TOP({TopRows}) \r\n\t{SelectColumns}\r\nfrom {SchemaTable} OBJ{Where}{OrderByStatement}"; + internal string SelectColumns => !Columns?.Any() ?? true ? "*" : string.Join(",\r\n\t", Columns.Where(c => !Exclude.ToList().Contains(c.ColumnName)).Select(c => c.ColumnName)); + internal string OrderByStatement => !OrderBy?.Any() ?? true ? "" : "\r\nOrder By " + string.Join(", ", OrderBy.Select(ob => $"{ob.ColumnName}{(ob.IsDescending ? " DESC" : "")}")); + + public Table(string schemaName, string tableName) + { + SchemaName = schemaName; + TableName = tableName; + Columns = new List(); + OrderBy = new List(); + } + + public Table(string schemaName, string tableName, IEnumerable columns) + : this(schemaName, tableName) + { + Columns = columns.ToList(); + } + + public Table(string schemaName, string tableName, IEnumerable columns, IEnumerable orderBy) + : this(schemaName, tableName, columns) + { + OrderBy = orderBy.ToList(); + } + + /// + /// + /// + /// + /// Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + /// + public void Init(IEnumerable orderBys, IEnumerable excludes = null, IEnumerable keyColumns = null, IEnumerable jsonColumns = null, string where = "") + { + if (orderBys != null) + OrderBys(orderBys); + if (excludes != null) + Excludes(excludes); + if (keyColumns != null) + KeyColumns(keyColumns); + if (jsonColumns != null) + JsonColumns(jsonColumns); + if (!string.IsNullOrEmpty(where)) + where = $"\r\nwhere {where}"; + } + + /// + /// Using 'D|' at the beginning of a column name implies that the sort order is descending for that column + /// + public void OrderBys(IEnumerable orderBys) + { + OrderBy.Clear(); + ((List)OrderBy).AddRange(orderBys.Where(o => Columns.Select(c => c.ColumnName).Contains(o.ColumnName, StringComparer.CurrentCultureIgnoreCase))); + } + + public void Excludes(IEnumerable excludes) + { + Exclude.Clear(); + ((List)Exclude).AddRange(excludes.Where(e => Columns.Select(c => c.ColumnName).Contains(e, StringComparer.CurrentCultureIgnoreCase))); + } + + public void KeyColumns(IEnumerable keyColumns) + { + KeyColumn.Clear(); + ((List)KeyColumn).AddRange(keyColumns.Where(kc => Columns.Select(c => c.ColumnName).Contains(kc, StringComparer.CurrentCultureIgnoreCase))); + } + + public void JsonColumns(IEnumerable jsonColumns) + { + Json.Clear(); + ((List)Json).AddRange(jsonColumns.Where(jc => Columns.Select(c => c.ColumnName).Contains(jc, StringComparer.CurrentCultureIgnoreCase))); + } +} + +public class Column +{ + public string ColumnName { get; set; } + public string DataType { get; set; } + public bool IsPrimaryKey { get; set; } + public Column(string columnName, string dataType = "", bool isPrimaryKey = false) + { + ColumnName = columnName; + DataType = dataType; + IsPrimaryKey = isPrimaryKey; + } +} + +public class OrderBy +{ + public string ColumnName { get; set; } + public bool IsDescending { get; set; } = false; + + public OrderBy(string columnName, bool isDescending = false) + { + ColumnName = columnName; + IsDescending = isDescending; + } + +} + +public class TablesAndColumns +{ + public string SchemaName { get; set; } + public IEnumerable TableNames { get; set; } + public TablesAndColumns(string schemaName, IEnumerable tables) + { + SchemaName = schemaName; + TableNames = tables; + } +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public IEnumerable OrderBy { get; set; } + public OrderByInformation(string tableName, IEnumerable columns) + { + TableName = tableName; + OrderBy = columns + .Select(c => + new OrderBy(c.StartsWith("D|") ? c.Substring(2) : c, + c.StartsWith("D|"))); + } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public ColumnsToExclude(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +public class JsonColumns +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public JsonColumns(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +#endregion + +#region Do the comparisons + +public void DoTheComparisons(Connections connections, IEnumerable
tables) +{ + foreach (var table in tables) + { + var sql = table.SqlSelect; + var dataLegacy = GetData(connections.Legacy, sql, table.TableName); + var dataUpdate = GetData(connections.Update, sql, table.TableName); + + var compare = new List(); + var jsonColumns = table.Json.ToList() ?? null; + dataLegacy.AsEnumerable().ToList() + .ForEach(legacyRow => + { + DataRow updateRow = default(DataRow); + if (table.KeyColumn.Any()) + { + var keys = string.Join("|", table.KeyColumn.Select(kc => $"{legacyRow.Field(kc)}")); + updateRow = dataUpdate.AsEnumerable() + .FirstOrDefault(y => keys == string.Join("|", table.KeyColumn.Select(kc => $"{y.Field(kc)}"))); + } + if (updateRow == null || JsonConvert.SerializeObject(legacyRow.ItemArray) != JsonConvert.SerializeObject(updateRow.ItemArray)) + compare.Add(new CompareSet(compare.Count, legacyRow, updateRow, jsonColumns)); + }); + dataUpdate.AsEnumerable().ToList() + .ForEach(updateRow => + { + DataRow legacyRow = default(DataRow); + if (table.KeyColumn.Any()) + { + var keys = string.Join("|", table.KeyColumn.Select(kc => $"{updateRow.Field(kc)}")); + legacyRow = dataLegacy.AsEnumerable() + .FirstOrDefault(y => keys == string.Join("|", table.KeyColumn.Select(kc => $"{y.Field(kc)}"))); + } + if (legacyRow == null) + compare.Add(new CompareSet(compare.Count, legacyRow, updateRow, jsonColumns)); + }); + if (compare.Any()) + { + compare.OrderBy(c => c.OrderBy) + .Dump($"{table.SchemaTable} ( {compare.Count()} / {dataLegacy.Rows.Count} / {dataUpdate.Rows.Count} rows )", TableDumpDepth); + } + else + { + "No differences found in data".Dump($"{table.SchemaTable} ( 0 / {dataLegacy.Rows.Count} / {dataUpdate.Rows.Count} rows )"); + } + } +} + +public class Connections +{ + public ServerInstance Legacy { get; set; } + public ServerInstance Update { get; set; } +} + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + + public ServerInstance(string server, string database) + { + Server = server; + Database = database; + } +} + +public DataTable GetData(ServerInstance serverInstance, string sql, string tableName) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var datatable = new DataTable(); + var adapter = new SqlDataAdapter(sql, conn); + try + { + adapter.Fill(datatable); + } + catch (Exception) + { + sql.Dump(nameof(sql)); + throw; + } + datatable.TableName = tableName; + return datatable; + } +} + +public class CompareSet +{ + internal int Row { get; set; } + internal IList ColumnNames { get; set; } + internal IList Legacy { get; set; } + internal IList Update { get; set; } + internal int OrderBy { get; set; } = 0; + public IList Rows { get; set; } + internal IList JsonColumns { get; set; } + public CompareSet(int row, DataRow right, DataRow left, IList jsonColumns) + { + Row = ++row; + if (right == null) + { + ColumnNames = left.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + } + else + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + } + Legacy = right?.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + OrderBy = (right != null ? 0 : 2) + (left != null ? 0 : 1); + JsonColumns = jsonColumns; + Rows = ColumnNames.Select((c, i) => new Row(row, c, Legacy?[i], Update?[i], JsonColumns?.Contains(c, StringComparer.CurrentCultureIgnoreCase) ?? false)).ToList(); + } + + public CompareSet(int row, DataRow right, DataRow left) + : this(row, right, left, null) + { + } + + object ToDump() => new + { + Row = $"{Row}", + Rows = Rows.Select(x => new + { + Column = (x.Left ?? "").Equals(x.Right ?? "") ? (object)x.Column : new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:lightyellow;color:black"), x.Column)), + Legacy = x.Left, + Update = x.Right + }) + }; + +} + +public class Row +{ + public int RowId { get; set; } + public string Column; + public bool IsJson; + public object Left; + public object Right; + + public Row(int row, string column, object left, object right) + { + RowId = row; + Column = column; + Left = left; + Right = right; + } + + public Row(int row, string column, object left, object right, bool isJson) + : this(row, column, left, right) + { + + IsJson = isJson; + if (!isJson) return; + if (left != null) + { + Left = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(left.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + if (right != null) + { + Right = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(right.ToString(), + new JsonSerializerSettings + { + Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) + { + args.ErrorContext.Handled = true; + } + }), Newtonsoft.Json.Formatting.Indented); + } + } + +} + +#endregion \ No newline at end of file diff --git a/StarterSet Validator Task Migration Issues.linq b/StarterSet Validator Task Migration Issues.linq new file mode 100644 index 0000000..e65d9ba --- /dev/null +++ b/StarterSet Validator Task Migration Issues.linq @@ -0,0 +1,65 @@ + + + 4f885e7e-d8bb-427c-a54e-8e3e1c3137a7 + true + IOAK-SQL-LOG-01.sdt.local + elog10 prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +(from log in ViewTaskEngineLogDetailed + where log.TaskName == "StarterSet Validator Task" + orderby log.TimeStamp descending + select new { log.TaskName, log.TaskEngineVersion, log.ServerName, log.DatabaseName, log.OrgPin, log.PhysicalName, log.Description}).Dump(); diff --git a/StrataJazz FileSize Report.linq b/StrataJazz FileSize Report.linq new file mode 100644 index 0000000..2a41c88 --- /dev/null +++ b/StrataJazz FileSize Report.linq @@ -0,0 +1,128 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var baseDir = @"D:\Git\Jazz"; + + var solution = Path.Combine(baseDir, "veracode.sln"); + var regex = new Regex(@"[^=]*=\s+""([^""]*)"",\s""([^""]*)"".*"); + var veracodeProjectFolders = File.ReadAllLines(solution) + .Where(l => l.StartsWith("Project(")) + .Where(l => regex.Match(l).Success) + .ToList(); + var fileTypes = new Regex(@"^\.vb$|^\.css?$|^\.jsx?$|^\.html$|^\.as[achmp]{1}x$|^\.xs[xd]{1}$"); + //veracodeProjectFolders.Dump(); + var vpnames = veracodeProjectFolders + .Where(l => !string.IsNullOrEmpty(regex.Replace(l, "$1"))) + .ToDictionary(l => regex.Replace(l, "$1"), l => Path.GetDirectoryName(Path.Combine(baseDir, regex.Replace(l, "$2")))); + var vpf = vpnames.Values.ToList(); + + //vpnames.Dump(); + //vpf.ConvertAll(v => Path.GetDirectoryName(Path.Combine(baseDir, v))).Dump(); + + baseDir = Path.Combine(baseDir, @"Code\"); + var dirs = Directory.EnumerateDirectories(baseDir) + .Where(d => vpf.Contains(d)) + .ToList() + .ConvertAll(d => d.Replace(baseDir, "")); + var fileSizes = new Dictionary>(); + var fileExtensions = new List(); + foreach (var dir in dirs) + { + var path = Path.Combine(baseDir, dir); + //$"{baseDir} + {dir} = {path}".Dump(); + foreach (var file in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) + { + if (file.Contains(@"\obj\") || file.Contains(@"\bin\")) continue; + var fi = new FileInfo(file); + fileExtensions.Add(fi.Extension); + if (!fileTypes.IsMatch(fi.Extension)) continue; + var fDir = fi.DirectoryName.Replace(baseDir, "").Split(Path.DirectorySeparatorChar)[0]; + var fSize = fi.Length; + if (!fileSizes.ContainsKey(dir)) + fileSizes.Add(dir, new Dictionary()); + if (!fileSizes[dir].ContainsKey(fi.Extension)) + fileSizes[dir].Add(fi.Extension, 0); + fileSizes[dir][fi.Extension] += fSize; + } + } + var report = fileSizes.Keys.ToList() + .ConvertAll(key => fileSizes[key].Keys.ToList() + .ConvertAll(ext => new DirectorySize { Directory = key, FileExtension = ext, fileSize = fileSizes[key][ext] })) + .SelectMany(x => x.Select(y => y)); + report.Sum(x => x.fileSize).BytesToString().Dump("Total Source"); + report.OrderBy(r => r.Directory).ThenBy(r => r.FileExtension).Dump(); + fileExtensions.Distinct().OrderBy(e => e).Dump(); +} + +// Define other methods and classes here + +public class DirectorySize +{ + public string Directory { get; set; } + public string FileExtension { get; set; } + public long fileSize { get; set; } + object ToDump() => new + { + Directory, + FileExtension, + FileSize = new XElement("LINQPad.HTML", + new XElement("div", + new XAttribute("align", "right"), + new XAttribute("style", $"background-color:{((fileSize > Math.Pow(1024, 3)) ? "red" : (fileSize > Math.Pow(1024, 2)) ? "violet" : "white")};"), + $"{fileSize.BytesToString()}".PadLeft(10))), + }; + +} \ No newline at end of file diff --git a/Testing the IsFileInDirectory function.linq b/Testing the IsFileInDirectory function.linq new file mode 100644 index 0000000..1a88cc6 --- /dev/null +++ b/Testing the IsFileInDirectory function.linq @@ -0,0 +1,87 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +Sub Main + Dim aListOfDirectories = New List(Of String) + aListOfDirectories.Add("d:\Git") + 'This file does not exist + IsFileInDirectory("D:\Git\thom.txt", aListOfDirectories).Dump("D:\Git\thom.txt") + MyIsFileInDirectory("D:\Git\thom.txt", aListOfDirectories).Dump("D:\Git\thom.txt") + 'This file does exist + IsFileInDirectory("D:\Git\new migration.txt", aListOfDirectories).Dump("D:\Git\new migration.txt") + MyIsFileInDirectory("D:\Git\new migration.txt", aListOfDirectories).Dump("D:\Git\new migration.txt") + MyIsFileInDirectory("D:\Git\new migration.txt", aListOfDirectories).Equals(IsFileInDirectory("D:\Git\new migration.txt", aListOfDirectories)).Dump("My Equals not My") +End Sub + +' Define other methods and classes here +Public Shared Function MyIsFileInDirectory(ByVal aFilePath As String, ByVal aListOfDirectories As List(Of String)) As Boolean + Dim fileObject = New System.IO.FileInfo(aFilePath) + If Not fileObject.Exists + Return False + End If + Return aListOfDirectories _ + .Select(Function(allowedDir) New System.IO.DirectoryInfo(allowedDir)) _ + .Any(Function(testDirectory) fileObject.Directory.FullName.Equals(testDirectory.FullName.TrimEnd("\"), StringComparison.OrdinalIgnoreCase)) +End Function + +Public Shared Function IsFileInDirectory(ByVal aFilePath As String, ByVal aListOfDirectories As List(Of String)) As Boolean + Dim fileObject = New System.IO.FileInfo(aFilePath) + For Each allowedDir In aListOfDirectories + Dim testDirectory = New System.IO.DirectoryInfo(allowedDir) + If fileObject.Directory.FullName.Equals(testDirectory.FullName, StringComparison.OrdinalIgnoreCase) Then + Return True + End If + Next + Return False +End Function \ No newline at end of file diff --git a/TimeZones.linq b/TimeZones.linq new file mode 100644 index 0000000..fdc7c15 --- /dev/null +++ b/TimeZones.linq @@ -0,0 +1,76 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + TimeZoneNames + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.Globalization + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + TimeZoneNames + + +TimeZoneInfo.GetSystemTimeZones().Dump(); +TimeZoneInfo.GetSystemTimeZones() + .SelectMany(tzi => new [] { + TZNames.GetAbbreviationsForTimeZone(tzi.Id, "en-US").Daylight != TZNames.GetAbbreviationsForTimeZone(tzi.Id, "en-US").Standard + ? new { Key = tzi.Id.Replace("Standard", "Daylight"), Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, "en-US").Daylight } + : new { Key = tzi.Id, Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, "en-US").Daylight }, + new { Key = tzi.Id, Value = TZNames.GetAbbreviationsForTimeZone(tzi.Id, "en-US").Standard }}) + .GroupBy(x => x.Key) + .Select(g => g.First()) + .ToDictionary(item => item.Key, item => item.Value) + .OrderBy(item => item.Key) + .Dump(); \ No newline at end of file diff --git a/UV CaseTypeConfig Parsing.linq b/UV CaseTypeConfig Parsing.linq new file mode 100644 index 0000000..7195ecc --- /dev/null +++ b/UV CaseTypeConfig Parsing.linq @@ -0,0 +1,95 @@ + + Newtonsoft.Json + + + +void Main() +{ +var CaseTypConfigJSON = @"{""SOIROMInclusions"":[{""SOI"":""1"",""ROM"":""1""},{""SOI"":""1"",""ROM"":""2""},{""SOI"":""1"",""ROM"":""3""},{""SOI"":""1"",""ROM"":""4""},{""SOI"":""2"",""ROM"":""1""},{""SOI"":""2"",""ROM"":""2""},{""SOI"":""2"",""ROM"":""3""},{""SOI"":""2"",""ROM"":""4""},{""SOI"":""3"",""ROM"":""1""},{""SOI"":""3"",""ROM"":""2""},{""SOI"":""3"",""ROM"":""3""},{""SOI"":""3"",""ROM"":""4""},{""SOI"":""4"",""ROM"":""1""},{""SOI"":""4"",""ROM"":""2""},{""SOI"":""4"",""ROM"":""3""},{""SOI"":""4"",""ROM"":""4""}],""AgeCohortIDInclusions"":[5,6,7,8,9,10,3,4],""PhysicianIDExclusions"":[],""StandardDeviationExcludedTypeEnum"":0,""LengthOfStayThreshold"":0,""CPTCodes"":[],""PatientTypeRollupIDInclusions"":[3,2,1],""PhysicianMinVolume"":0}"; +JsonConvert.DeserializeObject(CaseTypConfigJSON).Dump(); +} + +// Define other methods and classes here + +public enum StandardDeviationExclusions +{ + None = 0, + TwoStdDev = 1, + ThreeStdDev = 2, + CustomLOSOutlier = 3 +} + +[Serializable] +public class CaseTypeConfiguration //: ICaseTypeConfiguration +{ + public int PhysicianMinVolume { get; set; } = 0; +} + +public class DRGCaseTypeConfiguration : CaseTypeConfiguration//, IDRGCaseTypeConfiguration +{ + // ReSharper disable once InconsistentNaming + public List AgeCohortIDInclusions { get; set; } = new List(); + public List PhysicianIDExclusions { get; set; } = new List(); + public StandardDeviationExclusions StandardDeviationExcludedTypeEnum { get; set; } = StandardDeviationExclusions.None; + public int LengthOfStayThreshold { get; set; } = 0; + public HashSet CPTCodes { get; set; } = new HashSet(); + public List PatientTypeRollupIDInclusions { get; set; } = new List(); +} + +[Serializable] +public class SOIROMInclusion : IEquatable +{ + + public string SOI { get; set; } + public string ROM { get; set; } + + public SOIROMInclusion() + { + + } + + public SOIROMInclusion(string soi, string rom) + { + SOI = soi; + ROM = rom; + } + + public SOIROMInclusion(int soi, int rom) + { + SOI = soi.ToString(); + ROM = rom.ToString(); + } + + public bool Equals(SOIROMInclusion other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(ROM, other.ROM, StringComparison.OrdinalIgnoreCase) && + string.Equals(SOI, other.SOI, StringComparison.OrdinalIgnoreCase); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((SOIROMInclusion)obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((ROM != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(ROM) : 0) * 397) ^ + (SOI != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(SOI) : 0); + } + } + +} + +public class APRDRGCaseTypeConfiguration : DRGCaseTypeConfiguration +{ + // ReSharper disable once InconsistentNaming + public List SOIROMInclusions { get; set; } = new List(); + +} diff --git a/UV Export Analysis.linq b/UV Export Analysis.linq new file mode 100644 index 0000000..a8b34e8 --- /dev/null +++ b/UV Export Analysis.linq @@ -0,0 +1,122 @@ + + LinqToCsv + LINQtoCSV + + +void Main() +{ + var path = @"D:\Users\tlamb\Downloads"; + var utilizationFile = @"CI_Sepsis LOS - Pharmacy_All Physicians_Utilization_01-15-2021.csv"; + //@"CI_Sepsis LOS - Pharmacy_All Physicians_Utilization_01-14-2021.csv"; + var trackingDetailsFile = @"CI_Sepsis LOS - Pharmacy_01-14-2021 Tracking Details.csv"; + + var inputFileDescription = new CsvFileDescription + { + SeparatorChar = ',', + FirstLineHasColumnNames = true + }; + + var cc = new CsvContext(); + + var trackingDetails = cc.Read(Path.Combine(path, trackingDetailsFile), inputFileDescription) + .GroupBy(td => td.Charge_Description, (g, d) => new Consolidated + { + Charge_Code = g, + TotalDirectVariableCost = d.Sum(u => u.TotalDirectVariableCost) + }) + .OrderBy(td => td.Charge_Code); + + var utilization = cc.Read(Path.Combine(path, utilizationFile), inputFileDescription) + .GroupBy(u => u.Charge_Code, (g, d) => d.Select(u => new Consolidated + { + Charge_Code = u.Charge_Code, + Baseline_TotalDirectVariableCost = u.Baseline_TotalDirectVariableCost, + Tracking_TotalDirectVariableCost = u.Tracking_TotalDirectVariableCost + })) + .SelectMany(u => u) + .OrderBy(u => u.Charge_Code); + + var consolidated = from td in utilization + join u in trackingDetails on td.Charge_Code equals u.Charge_Code into g + from x in g.DefaultIfEmpty() + select new Consolidated + { + Charge_Code = x?.Charge_Code ?? td.Charge_Code, + TotalDirectVariableCost = x?.TotalDirectVariableCost ?? 0.0d, + Baseline_TotalDirectVariableCost = td?.Baseline_TotalDirectVariableCost ?? 0.0d, + Tracking_TotalDirectVariableCost = td?.Tracking_TotalDirectVariableCost ?? 0.0d + }; + cc.Write(consolidated, Path.Combine(path, "consolidated.csv"), inputFileDescription); +} + +// Define other methods and classes here +public class TrackingDetails +{ + public string Encounter { get; set; } + public DateTime Admit_Date { get; set; } + public DateTime Discharge_Date { get; set; } + public string Physician { get; set; } + public string Physician_Group { get; set; } + public DateTime Date_of_Service { get; set; } + public string Rollup { get; set; } + public string Charge_Description { get; set; } + public int UOS { get; set; } + public string Unit_Direct_Variable_Cost { get; set; } + public string Total_Direct_Variable_Cost { get; set; } + public double TotalDirectVariableCost + { + get + { + return double.TryParse(Total_Direct_Variable_Cost.Replace("$", "").Replace("(", "-").Replace(")", ""), out var result) ? result : 0.0d; + } + } +} + +public class Utilization +{ + public string Rollup { get; set; } + public string Charge_Code { get; set; } + public string Direct_Variable_Cost { get; set; } + public string x { get; set; } + public string Cases1 { get; set; } + public string Quantity1 { get; set; } + public string Pct_of_Total_Cases1 { get; set; } + public string Qty_Used_Cases1 { get; set; } + public string Cases2 { get; set; } + public string Quantity2 { get; set; } + public string Pct_of_Total_Cases2 { get; set; } + public string Qty_Used_Cases2 { get; set; } + public string Pct_of_Total_Cases3 { get; set; } + public string Qty_Used_Cases3 { get; set; } + public string b { get; set; } + public string CostPerCase1 { get; set; } + public string CostPerCase2 { get; set; } + public string CostPerCase3 { get; set; } + public string Total_Direct_Variable_Cost1 { get; set; } + public string Total_Direct_Variable_Cost2 { get; set; } + public string Total_Direct_Variable_Cost3 { get; set; } + public double Baseline_TotalDirectVariableCost + { + get + { + return string.IsNullOrEmpty(Total_Direct_Variable_Cost1) ? 0.0d + : double.TryParse(Total_Direct_Variable_Cost1.Replace("$-", "0").Replace("$", "").Replace("(", "-").Replace(")", ""), out var result) ? result : 0.0d; + } + } + public double Tracking_TotalDirectVariableCost + { + get + { + return string.IsNullOrEmpty(Total_Direct_Variable_Cost2) ? 0.0d + : double.TryParse(Total_Direct_Variable_Cost2.Replace("$-", "0").Replace("$", "").Replace("(", "-").Replace(")", ""), out var result) ? result : 0.0d; + } + } +} + +public class Consolidated +{ + public string Charge_Code { get; set; } + public double TotalDirectVariableCost { get; set; } + public double Baseline_TotalDirectVariableCost { get; set; } + public double Tracking_TotalDirectVariableCost { get; set; } +} \ No newline at end of file diff --git a/Understanding UNC PayPeriods.linq b/Understanding UNC PayPeriods.linq new file mode 100644 index 0000000..940b657 --- /dev/null +++ b/Understanding UNC PayPeriods.linq @@ -0,0 +1,193 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var validPayPeriods = PayPeriodCycles + .GroupBy(g => new { g.PayCycleID, g.PayCycleName }, (g, pp) => + new + { + g.PayCycleID, + g.PayCycleName, + PayPeriods = pp.Select(p => + new payperiodtiming + { + PayPeriodID = p.PayPeriodID, + PeriodEndCalendarDate = p.PeriodEndCalendarDate, + PeriodStartCalendarDate = p.PeriodStartCalendarDate + }).OrderByDescending(p => p.PeriodEndCalendarDate).Take(6) + }) + .SelectMany(g => g.PayPeriods); + + DeptPayPeriods + .ToList() + // .OrderBy(dpp => dpp.DepartmentID) + // .ThenByDescending(dpp => dpp.PayPeriodID) + .GroupBy(dpp => new { dpp.DepartmentID, dpp.Department }, (g, dpp) => new deptpayperiodtiming + { + DepartmentID = g.DepartmentID, + Department = g.Department, + PayPeriodTimings = dpp.Select(d => d.PayPeriodID).Distinct() + .Join(validPayPeriods, x => x, vpp => vpp.PayPeriodID, (x, vpp) => vpp) + .OrderByDescending(d => d.PayPeriodID) + }) + .Where(dpp => dpp.PayPeriodTimings.Any()) + .Dump("Department PayPeriods"); +} + +public void ShowCycles() +{ + PayPeriodCycles + .GroupBy(g => new { g.PayCycleID, g.PayCycleName }, (g, pp) => + new + { + g.PayCycleID, + g.PayCycleName, + PayPeriods = pp.Select(p => + new payperiodtiming + { + PayPeriodID = p.PayPeriodID, + PeriodEndCalendarDate = p.PeriodEndCalendarDate, + PeriodStartCalendarDate = p.PeriodStartCalendarDate + }).OrderByDescending(p => p.PeriodEndCalendarDate).Take(6) + }) + .Dump("Pay Period Cycles"); +} + +public IEnumerable DeptPayPeriods => (from fact in FactPayrollSampledPayPeriods + join dept in DimDepartments on fact.DepartmentID equals dept.DepartmentID + select new deptpayperiod + { + PayPeriodID = fact.PayPeriodID, + DepartmentID = fact.DepartmentID, + Department = dept.Name + }).Union((from fact in ViewPrimaryStatisticsStaffingByPayPeriod + join dept in DimDepartments on fact.DepartmentID equals dept.DepartmentID + select new deptpayperiod + { + PayPeriodID = fact.PayPeriodID, + DepartmentID = fact.DepartmentID, + Department = dept.Name + })).Distinct(); + +public IEnumerable PayPeriodCycles => from pp in DimPayPeriods + where pp.PeriodEndCalendarDate < DateTime.Now + select new payperiodcycle + { + PayPeriodID = pp.PayPeriodID, + PayCycleID = pp.PayCycleID, + PayCycleName = pp.PayCycleName, + PeriodEndCalendarDate = pp.PeriodEndCalendarDate, + PeriodStartCalendarDate = pp.PeriodStartCalendarDate + }; + +// Define other methods and classes here + +public class deptpayperiod +{ + public short PayPeriodID { get; set; } + public int DepartmentID { get; set; } + public string Department { get; set; } +} + +public class deptpayperiodtiming +{ + public int DepartmentID { get; set; } + public string Department { get; set; } + internal IEnumerable PayPeriodTimings { get; set; } + public IDictionary PayPeriods => + PayPeriodTimings.ToDictionary(ppt => ppt.PayPeriodID, + ppt => new payperioddate + { + PeriodStartCalendarDate = ppt.PeriodStartCalendarDate, + PeriodEndCalendarDate = ppt.PeriodEndCalendarDate + }); + public DateTime? PeriodStartDate => PayPeriodTimings.OrderByDescending(ppt => ppt.PayPeriodID).First().PeriodStartCalendarDate; + public DateTime? PeriodEndDate => PayPeriodTimings.OrderByDescending(ppt => ppt.PayPeriodID).First().PeriodEndCalendarDate; +} + +public class payperioddate +{ + public DateTime PeriodEndCalendarDate { get; set; } + public DateTime? PeriodStartCalendarDate { get; set; } + object ToDump() => new + { + PeriodStartDate = $"{PeriodStartCalendarDate:yyyy MM dd}", + PeriodEndDate = $"{PeriodEndCalendarDate:yyyy MM dd}" + }; +} + +public class payperiodtiming : payperioddate +{ + public short PayPeriodID { get; set; } + object ToDump() => new + { + PayPeriodID = $"{PayPeriodID}", + PeriodStartDate = $"{PeriodStartCalendarDate:yyyy MM dd}", + PeriodEndDate = $"{PeriodEndCalendarDate:yyyy MM dd}" + }; +} + +public class payperiodcycle : payperiodtiming +{ + public int PayCycleID { get; set; } + public string PayCycleName { get; set; } +} \ No newline at end of file diff --git a/Update StrataSphere Reports DefinitionsJson.linq b/Update StrataSphere Reports DefinitionsJson.linq new file mode 100644 index 0000000..be24fb5 --- /dev/null +++ b/Update StrataSphere Reports DefinitionsJson.linq @@ -0,0 +1,88 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +//var reportList = Reports.ToList(); +var reports = Reports.ToList() +.Where(rpt => !string.IsNullOrEmpty(rpt.ReportSetupJson) && rpt.ReportSetupJson.StartsWith("{") && rpt.ReportSetupJson.EndsWith("}")) +.Select(rpt => new { rpt, reportSetup = JObject.Parse(rpt.ReportSetupJson)}) +.ToList(); +//reports.Dump(); +//reports.ForEach(rpt => rpt.reportSetup.Dump()); + +var definitions = reports +.Select(rpt => new { rpt.rpt, definitions = rpt.reportSetup.SelectTokens("..StandardDefinitionGUID") +.Where(x => x.Value() != Guid.Empty.ToString()) +.Select(x => x.Value()).ToList()}) +.ToList(); +foreach(var def in definitions.Where(def => def.definitions.Count() > 0)) +{ + var defJson = JsonConvert.SerializeObject(def.definitions); + defJson.Dump(); + def.rpt.DefinitionsJson = defJson; + SubmitChanges(); +} diff --git a/Update TEScheduleTask for Starter Set Report Card Validator.linq b/Update TEScheduleTask for Starter Set Report Card Validator.linq new file mode 100644 index 0000000..7d50b48 --- /dev/null +++ b/Update TEScheduleTask for Starter Set Report Card Validator.linq @@ -0,0 +1,280 @@ + + + 4f885e7e-d8bb-427c-a54e-8e3e1c3137a7 + true + IOAK-SQL-LOG-01.sdt.local + jazz log prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.Dynamic + System.IO.Compression + System.Threading.Tasks + System.Data.Common + + +#region *** Enumerations *** + +public enum QueryRegions +{ + Production, + Training, + Oak, + Dev +} + +#endregion + +#region *** Options *** + +public static QueryRegions queryRegion = QueryRegions.Production; +public static int timeoutInMinutes = 2; + +#endregion + +#region *** Database Selection *** + +public static string[] appVersions = { // This is a list of appVersions to filter for in the database list +}; +public static string[] serverExclusions = { // This is a list of servers to exclude from the database list + @"paonsql19.sdt.local\instance1", + @"paonsql17.sdt.local\instance1", + @"p0555-sql-01.sdt.local\instance1", + "P0000-sql-01.sdt.local", + "P9900-SQL-03.sdt.local", + "P9900-sql-05.sdt.local" +}; +public static string[] dbExclusions = { // This is a list of database physical names to exclude from the database list +}; +public static string[] targetOrgPins = { // This is a list of org pins to target in the database list +}; +public static string[] targetServers = { // This is a list of servers to target in the database list +}; +public static string[] targetDBs = { // This is a list of database physicial names to target in the database list +}; + +#endregion *** Options *** + +#region *** SMC Settings and queries *** + +public static string smcSql => @"SELECT di.ServerName, di.DatabaseGUID, di.DatabaseName, di.PhysicalName, di.OrgPin, di.AppVersion, di.Description +FROM [dbo].[viewDatabaseInfo] di +WHERE 1=1" ++ (queryRegion == QueryRegions.Dev +? @" + AND di.PhysicalName like 'jazz%'" +: $@" + AND di.PhysicalName like 'jazz {(queryRegion != QueryRegions.Production ? "tst" : "prd")}%' + AND di.ServerName like 'p%'"); +public static string smcServer { get; set; } +public static string smcDB { get; set; } + +#endregion + +#region *** Program variables and settings *** + +public static IOrderedEnumerable databases => GetDatabases(); + +#endregion + +void Main() +{ + //databases.OrderBy(d => d.Server).ThenBy(d => d.PhysicalName).Dump($"{queryRegion} {nameof(databases)}"); + var workList = databases.OrderBy(d => d.Server).ThenBy(d => d.PhysicalName).ToList(); + var sqlQuery = @"select Name, t.Time, RepeatType, IsDisabled, HasRun, LastSubmittedDate, LastRunDate from TEScheduledTask t where name = 'Starter Set Report Card Validator'"; + var start = new DateTime(2020, 3, 23, 3, 0, 0); + var interval = 3; // minutes + workList.ForEach(db => + { + try + { + var connectionString = BuildConnectionString(db.Server, db.PhysicalName); + var database = new Database(); + var results = SelectDynamic(database, connectionString, sqlQuery); + if (results.Any()) + { + //var updateStatement = $@"Update TEScheduledTask set Time = '{start.ToString("hh:mm:ss tt")}' where name = 'Starter Set Report Card Validator'"; + //ExecuteCommand(database, connectionString, updateStatement); + //var after = SelectDynamic(database, connectionString, sqlQuery); + new + { + connectionString, + //updateStatement, + results//, + //after + }.Dump(); + + start = start.AddMinutes(interval); + } + } + catch (SqlException sqlEx) + { + sqlEx.Dump(); + return; + } + }); +} + +public class Database +{ + public string Server { get; set; } + public Guid DatabaseGuid { get; set; } + public string DatabaseName { get; set; } + public string PhysicalName { get; set; } + public string OrgPin { get; set; } + public string AppVersion { get; set; } + public string Description { get; set; } + public Dictionary Fields { get; set; } + + public Database() + { + + } + + public Database(DataRow dr) + { + Server = dr.Field("ServerName"); + DatabaseGuid = dr.Field("DatabaseGuid"); + DatabaseName = dr.Field("DatabaseName"); + PhysicalName = dr.Field("PhysicalName"); + OrgPin = dr.Field("OrgPin"); + AppVersion = dr.Field("AppVersion"); + Description = dr.Field("Description"); + Fields = new Dictionary(); + foreach (DataColumn column in dr.Table.Columns) + { + var index = dr.Table.Columns.IndexOf(column); + Fields.Add(column.ColumnName, dr[index].ToString()); + } + } + + object ToDump() => (object)new + { + Server, + DatabaseGuid, + DatabaseName, + PhysicalName, + OrgPin, + AppVersion, + Description + }; +} + +public static IOrderedEnumerable GetDatabases() +{ + switch (queryRegion) + { + case QueryRegions.Production: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc prod"; + break; + case QueryRegions.Training: + smcServer = "ioak-sql-smc-01"; + smcDB = "smc training"; + break; + case QueryRegions.Oak: + smcServer = "ioak-sql-smc-01.sdt.local"; + smcDB = "smc qa"; + break; + default: + smcServer = "DDEN-SQL-SMC-01.sdt.local"; + smcDB = "smc dev"; + break; + } + List databases = new List(); + var connStr = BuildConnectionString(smcServer, smcDB); + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(smcSql, conn); + command.CommandType = CommandType.Text; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var table = new DataTable(); + database.Tables.Add(table); + table.Load(reader); + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + databases = database.Tables[0].AsEnumerable().Select(dr => new Database(dr)).ToList(); + databases = databases.Where(dr => !dbExclusions.Contains(dr.PhysicalName) && !serverExclusions.Contains(dr.Server)).ToList(); + if (targetOrgPins.Any()) + databases = databases.Where(dr => targetOrgPins.Contains(dr.OrgPin)).ToList(); + if (targetServers.Any()) + databases = databases.Where(dr => targetServers.Contains(dr.Server)).ToList(); + if (targetDBs.Any()) + databases = databases.Where(dr => targetDBs.Contains(dr.PhysicalName)).ToList(); + if (appVersions.Any()) + databases = databases.Where(dr => appVersions.Contains(dr.AppVersion)).ToList(); + } + return databases + .OrderBy(d => d.Server).ThenBy(d => d.PhysicalName); +} + +public static void ExecuteCommand(Database db, string connStr, string sql) +{ + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(sql, conn); + command.CommandType = CommandType.Text; + command.CommandTimeout = (int)TimeSpan.FromMinutes(timeoutInMinutes).TotalSeconds; + conn.Open(); + try + { + command.ExecuteNonQuery(); + conn.Close(); + } + catch (SqlException sqlEx) + { + sqlEx.Dump(); + } + } +} + +public static IEnumerable SelectDynamic(Database db, string connStr, string sql) +{ + using (var conn = new SqlConnection(connStr)) + { + var command = new SqlCommand(sql, conn); + command.CommandType = CommandType.Text; + command.CommandTimeout = (int)TimeSpan.FromMinutes(timeoutInMinutes).TotalSeconds; + var database = new DataSet(); + conn.Open(); + using (DbDataReader reader = command.ExecuteReader()) + { + while (true) + { + var names = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList(); + foreach (IDataRecord record in reader as IEnumerable) + { + var expando = new ExpandoObject() as IDictionary; + foreach (var name in names) + expando[name] = record[name]; + + yield return expando; + } + if (reader.IsClosed || !reader.NextResult()) break; + } + } + conn.Close(); + } +} + +public static string BuildConnectionString(string server, string database, string username = null, string password = null) +{ + return username == null + ? $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;" + : $"data source={server};initial catalog='{database}';User ID={username};pwd={password}"; +} diff --git a/User Role Department PayPeriod query.linq b/User Role Department PayPeriod query.linq new file mode 100644 index 0000000..5f9054d --- /dev/null +++ b/User Role Department PayPeriod query.linq @@ -0,0 +1,241 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +/* +(from roleDetail in ViewS3RoleAssignmentDetail +where roleDetail.RoleName.StartsWith("MR ") +&& roleDetail.LootID.Contains("MRDEPT|") +select roleDetail.RoleName) +.Distinct() +.OrderBy(p => p).ToList() +.Aggregate("var roles = new [] { ", (x, y) => x + $"\"{y}\", ").TrimEnd(", ".ToCharArray()) + " }" +*/ +void Main() +{ + var userNames = new List{ + "dachee" + }; + // var userGUIDs = from up in UserProfiles + // where userNames.Contains(up.UserName) + // select up.UserGUID; + // new List{ + // //new Guid("0e8a4d58-f9c1-4a49-837c-dd7db45793fe") + // new Guid("76CD86B8-D769-4AAE-9083-F8E6D005AA9D") + // }; + var users = (from user in UserProfiles + select new User + { + UserInfo = new UserInfo + { + UserGUID = user.UserGUID, + UserName = user.UserName, + NameFirst = user.NameFirst, + NameLast = user.NameLast, + EmailAddress = user.EmailAddress + } + }) + .Where(u => userNames.Contains(u.UserInfo.UserName)) + .ToList(); + var roles = new[] { +// "MR - Commenter", + "MR - Director", + "MR - Exec Director AVP", + "MR - Executive", +// "MR - Finance", + "MR - Manager", +// "MR - Read Only", +// "MR - Read Write Only", + "MR - Vice President" + }; + users + .ForEach(u => + { + int x; + u.Roles = (from roleDetail in ViewS3RoleAssignmentDetail + where roleDetail.UserGUID == u.UserInfo.UserGUID + select roleDetail.RoleName).Distinct().OrderBy(r => r).ToList(); + u.DepartmentIDs = (from roleDetail in ViewS3RoleAssignmentDetail + where roleDetail.UserGUID == u.UserInfo.UserGUID + && roleDetail.LootID.Contains("MRDEPT|") + && roles.Contains(roleDetail.RoleName) + select new { depts = roleDetail.LootID.Split('|').ToList() }) + .ToList().SelectMany(d => d.depts).Where(d => int.TryParse(d, out x)).ToList().ConvertAll(int.Parse).Distinct() + .ToList(); + u.DeptPayPeriods = (from fact in FactDepartmentProductivityMetrics + join pp in DimPayPeriods on fact.PayPeriodID equals pp.PayPeriodID + where u.DepartmentIDs.Contains(fact.DepartmentID) + && pp.PeriodEndCalendarDate < new DateTime(2019, 6, 17) + && pp.PeriodStartCalendarDate.HasValue + orderby pp.PeriodStartCalendarDate descending + select new { fact.DepartmentID, pp.PayPeriodID, PeriodStartCalendarDate = pp.PeriodStartCalendarDate.Value, pp.PeriodEndCalendarDate }) + .Distinct().ToList() + .GroupBy(dpp => dpp.DepartmentID, (key, grp) => new DeptPayPeriods + { + DepartmentID = key, + PayPeriods = grp.Select(g => new PayPeriod + { + PeriodID = g.PayPeriodID, + StartDate = g.PeriodStartCalendarDate, + EndDate = g.PeriodEndCalendarDate + }) + .ToList().OrderByDescending(pp => pp.StartDate).Take(6).ToList() + }).ToList(); + var payperiodIDs = u.DeptPayPeriods.SelectMany(d => d.PayPeriods.Select(pp => pp.PeriodID)); + var hours = from fact in FactPayrollSampledPayPeriods + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + join prodclass in DimProductiveClasses on paycode.ProductiveClassID equals prodclass.ProductiveClassID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where new[] { 1, 4 }.Contains(fact.TimeClassID) + && prodclass.Name == "Productive" + && u.DepartmentIDs.Contains(fact.DepartmentID) + && payperiodIDs.Contains(fact.PayPeriodID) + select new DeptPayPeriodTime(fact.DepartmentID, fact.PayPeriodID, fact.TimeClassID, fact.Hours, "hours"); + var dollars = from fact in FactPayrollSampledPayPeriods + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + //join prodclass in DimProductiveClasses on paycode.ProductiveClassID equals prodclass.ProductiveClassID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where new[] { 1, 4 }.Contains(fact.TimeClassID) + //&& prodclass.Name == "Productive" + && u.DepartmentIDs.Contains(fact.DepartmentID) + && payperiodIDs.Contains(fact.PayPeriodID) + select new DeptPayPeriodTime(fact.DepartmentID, fact.PayPeriodID, fact.TimeClassID, fact.Dollars, "dollars"); + var uos = from fact in ViewPrimaryStatisticsStaffingByPayPeriod + join payperiod in DimPayPeriods on fact.PayPeriodID equals payperiod.PayPeriodID + //join paycode in DimPayCodeGroups on fact.PayCodeGroupID equals paycode.PayCodeGroupID + //join prodclass in DimProductiveClasses on paycode.ProductiveClassID equals prodclass.ProductiveClassID + join department in DimDepartments on fact.DepartmentID equals department.DepartmentID + where new[] { 1, 4 }.Contains(fact.TimeClassID) + //&& prodclass.Name == "Productive" + && u.DepartmentIDs.Contains(fact.DepartmentID) + && payperiodIDs.Contains(fact.PayPeriodID) + select new DeptPayPeriodTime(fact.DepartmentID, fact.PayPeriodID, fact.TimeClassID, fact.Units.HasValue ? fact.Units.Value : 0.0m, "uos"); + var unitSummary = hours.ToList().Concat(dollars.ToList()).Concat(uos.ToList()) + .GroupBy(dppt => new { dppt.DepartmentID, dppt.PeriodID, dppt.TimeClassID, dppt.UnitType }, + (key, grp) => new DeptPayPeriodTime(key.DepartmentID, key.PeriodID, key.TimeClassID, + grp.Where(pp => u.DeptPeriodDict[pp.DepartmentID].Contains(pp.PeriodID)).Sum(i => i.Units), key.UnitType)) + .Where(item => u.DeptPeriodDict[item.DepartmentID].Contains(item.PeriodID)) + .OrderBy(item => item.DepartmentID) + .ThenByDescending(item => item.PeriodID).ToList(); + u.Units = unitSummary; + }); + users.Dump("Users"); + users//.Where(u => userGUIDs.Contains(u.UserInfo.UserGUID)) + .Aggregate("", (x, y) => x + y.DepartmentIDs.Aggregate(", ", (a, b) => $"{a}, {b}")).Substring(2) + .Dump(); + users//.Where(u => userGUIDs.Contains(u.UserInfo.UserGUID)) + .Aggregate("", (x, y) => x + y.DeptPayPeriods.SelectMany(dpp => dpp.PayPeriods.Select(pp => pp.PeriodID)).Distinct() + .Aggregate(", ", (a, b) => $"{a}, {b}")).Substring(2) + .Dump(); +} + +// Define other methods and classes here +public class User +{ + public UserInfo UserInfo { get; set; } + public List Roles { get; set; } + public List DepartmentIDs { get; set; } + public List DeptPayPeriods { get; set; } + internal Dictionary> DeptPeriodDict => + DeptPayPeriods.ToDictionary(dpp => dpp.DepartmentID, dpp => dpp.PayPeriods.Select(pp => pp.PeriodID).ToList()); + public List Units { get; set; } +} + +public class UserInfo +{ + public Guid UserGUID { get; set; } + public string UserName { get; set; } + public string NameFirst { get; set; } + public string NameLast { get; set; } + public string EmailAddress { get; set; } +} + +public class DeptPayPeriods +{ + public int DepartmentID { get; set; } + public List PayPeriods { get; set; } + //public List Units { get; set; } +} + +public class PayPeriod +{ + public short PeriodID { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } +} + +public class DeptPayPeriodTime +{ + public int DepartmentID { get; set; } + public short PeriodID { get; set; } + public byte TimeClassID { get; set; } + public decimal Units { get; set; } + public string UnitType { get; set; } + public DeptPayPeriodTime(int departmentID, short periodID, byte timeClassID, decimal units, string unitType) + { + DepartmentID = departmentID; + PeriodID = periodID; + TimeClassID = timeClassID; + Units = units; + UnitType = unitType; + } +} \ No newline at end of file diff --git a/UserRole query.linq b/UserRole query.linq new file mode 100644 index 0000000..b3dffb6 --- /dev/null +++ b/UserRole query.linq @@ -0,0 +1,71 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + +(from role in UserRoles +where role.Category == "MR" +select role).Dump(); + +} + +// Define other methods and classes here diff --git a/Validate Include and Exclude Regex's.linq b/Validate Include and Exclude Regex's.linq new file mode 100644 index 0000000..6a0f8af --- /dev/null +++ b/Validate Include and Exclude Regex's.linq @@ -0,0 +1,96 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var testset = new string[] { "3", "167", "168", "172", "4", "5", "6" }; + + var IncludeSolution = ""; + var ExcludeSolution = ""; + foreach (var check in checkInclude(IncludeSolution, testset)) + { + Console.WriteLine($"{check.Item1} is {check.Item2}"); + } + Console.WriteLine("\r\nExclude \"\""); + foreach (var check in checkExclude(ExcludeSolution, testset)) + { + Console.WriteLine($"{check.Item1} is {check.Item2}"); + } + Console.WriteLine("\r\nInclude \"^3$\""); + IncludeSolution = "^3$"; + foreach (var check in checkInclude(IncludeSolution, testset)) + { + Console.WriteLine($"{check.Item1} is {check.Item2}"); + } + ExcludeSolution = "^167$|^168$"; + Console.WriteLine("\r\nExclude \"^167$|^168$\""); + foreach (var check in checkExclude(ExcludeSolution, testset)) + { + Console.WriteLine($"{check.Item1} is {check.Item2}"); + } +} + +public IEnumerable> checkInclude(string pattern, string[] testset) +{ + var regex = string.IsNullOrEmpty(pattern) ? new Regex("^.+$") : new Regex(pattern); + return testset.ToList().ConvertAll(t => new Tuple(t, regex.IsMatch(t))); +} + +public IEnumerable> checkExclude(string pattern, string[] testset) +{ + var regex = string.IsNullOrEmpty(pattern) ? new Regex("^$") : new Regex(pattern); + return testset.ToList().ConvertAll(t => new Tuple(t, regex.IsMatch(t))); +} + +// Define other methods and classes here diff --git a/Veracode/Veracode CWE Analytics.linq b/Veracode/Veracode CWE Analytics.linq new file mode 100644 index 0000000..6950c09 --- /dev/null +++ b/Veracode/Veracode CWE Analytics.linq @@ -0,0 +1,387 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private XDocument xmlDoc = XDocument.Load(@"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Jazz_web_201911511115217.xml"); + +void Main() +{ + //xmlDoc.DumpFormatted(); + var cwes = ParseVeracodeReport(xmlDoc).Where(cwe => cwe.count > 0); + var flaws = (from cwe in xmlDoc.Descendants() + where cwe.Name.LocalName == "cwe" + && cwe.Attributes().Any(a => a.Name == "cweid") + orderby Int32.Parse(cwe.Attribute("cweid").Value) + select cwe.Descendants().Where(c => c.Name.LocalName == "flaw")); + flaws + .SelectMany(f => f.Select(x => new Flaw(x))) + .Where(x => new[] { 4, 5 }.Contains(x.severity) && !x.hasMitigations && x.remediation_status == "New") + .OrderByDescending(x => x.severity) + .ThenBy(x => x.categoryid) + .ThenBy(x => x.cweid) + .ThenBy(x => x.issueid).Dump(); + //DumpTop20(cwes); + // DumpSummary(cwes); + // DumpModules(cwes); + // DumpByCweID(cwes); +} + +void DumpTop20(IEnumerable cwes) +{ + cwes.Where(cwe => cwe.count > 1 && new[] { 78, 15, 89 }.Contains(cwe.id)) + .Select(cwe => new { cwe.severity, cwe.category, cwe.details }) + .OrderByDescending(cwe => cwe.severity) + .Dump($"Top 20: ({cwes.Where(cwe => cwe.count > 1).Count()})"); +} + +void DumpSummary(IEnumerable cwes) +{ + cwes.Where(cwe => cwe.count > 1) + .OrderByDescending(cwe => cwe.severity).ThenByDescending(cwe => cwe.count) + .Dump($"Summary: ({cwes.Where(cwe => cwe.count > 1).Count()})"); + +} + +void DumpModules(IEnumerable cwes) +{ + var regex = new Regex(@"\.Test\.|\.IntegrationTests\.|\.UnitTests\."); + var modules = from m in xmlDoc.Descendants() + where m.Name.LocalName == "module" && m.Parent.Name.LocalName == "modules" + select new Module(m, cwes); + modules.Where(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0) + .OrderBy(m => m.score).ThenByDescending(m => m.numberOfImportantFlaws) + .Dump($"Modules: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})"); +} + +void DumpByCweID(IEnumerable cwes) +{ + cwes.Where(cwe => cwe.count > 1) + .OrderBy(cwe => cwe.id).ToList() + .ForEach(cwe => cwe.details.Dump($"ID: {cwe.id} {cwe.name} ({cwe.count})")); + //JsonConvert.SerializeObject(cwes, Newtonsoft.Json.Formatting.Indented).Dump("Json"); +} + +internal IEnumerable ParseVeracodeReport(XDocument xmlDoc) +{ + return from module in xmlDoc.Descendants() + where module.Name.LocalName == "cwe" + && module.Attributes().Any(a => a.Name == "cweid") + orderby Int32.Parse(module.Attribute("cweid").Value) + select new Cwe(module); +} + +public static class IntExtensions +{ + public static string SeverityLabel(this int severity) + { + switch (severity) + { + case 5: return "Very High"; + case 4: return "High"; + case 3: return "Medium"; + case 2: return "Low"; + case 1: return "Very Low"; + default: return "Informational"; + } + } + public static string CategoryLabel(this int category) + { + switch (category) + { + case 18: return "OS Command Injection"; + case 19: return "SQL Injections"; + case 24: return "Untrusted Initialization"; + case 21: return "CRLF Injection"; + case 10: return "Credentials Management"; + default: return $"{category}"; + } + } +} + +internal class Module +{ + public string name { get; set; } + public int score { get; set; } + public int totalNumberOfFlaws => flawsBySeverity.Values.Sum(); + public int numberOfImportantFlaws => flawsBySeverity.Where(f => f.Key > 2).Select(f => f.Value).Sum(); + private Dictionary flawsBySeverity { get; set; } + + public string flawsSummaryInfo => totalNumberOfFlaws > 0 + ? flawsBySeverity.Where(f => f.Value > 0).OrderByDescending(f => f.Key).Aggregate(new StringBuilder("Severity\n"), (x, y) => + x.Append($"{y.Key.SeverityLabel()}: {y.Value}\r\n")).ToString().TrimEnd(new[] { '\r', '\n' }) + : ""; + + public List summary => totalNumberOfFlaws > 0 + ? flawsBySeverity.Where(f => f.Value > 0) + .OrderByDescending(f => f.Key) + .Select(y => new Severity + { + severity = y.Key, + Count = y.Value + }).ToList() + : new List(); + + public string flawListInfo => !flaws.Any() + ? "" : flaws.Aggregate(new StringBuilder("path\tfile\tline\ttype\n"), (x, y) => + x.AppendLine($"{(string.IsNullOrEmpty(y.source.sourcefile) ? "na" : Path.GetDirectoryName(y.source.sourcefile))}\t" + + $"{(string.IsNullOrEmpty(y.source.sourcefile) ? "na" : Path.GetFileName(y.source.sourcefile))}\t{y.source.line}\t{y.source.type}")).ToString(); + + public List flawList => !flaws.Any() ? null : flaws + .ConvertAll(y => (ModuleFlaw)y.source); + + private List flaws { get; set; } + + public Module(XElement module, IEnumerable cwes) + { + name = module.Attribute("name")?.Value; + score = Convert.ToInt32(module.Attribute("score")?.Value ?? "0"); + flawsBySeverity = new Dictionary(); + flawsBySeverity[0] = Convert.ToInt32(module.Attribute("numflawssev0")?.Value ?? "0"); + flawsBySeverity[1] = Convert.ToInt32(module.Attribute("numflawssev1")?.Value ?? "0"); + flawsBySeverity[2] = Convert.ToInt32(module.Attribute("numflawssev2")?.Value ?? "0"); + flawsBySeverity[3] = Convert.ToInt32(module.Attribute("numflawssev3")?.Value ?? "0"); + flawsBySeverity[4] = Convert.ToInt32(module.Attribute("numflawssev4")?.Value ?? "0"); + flawsBySeverity[5] = Convert.ToInt32(module.Attribute("numflawssev5")?.Value ?? "0"); + var cx = cwes.Where(c => c.details.Any(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase))); + flaws = cx.SelectMany(c => c.details.Where(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase)).Select(d => new ModuleFlaw(d))) + .GroupBy(d => $"{d.type}{d.sourcefile}{d.line}") + .Select(grp => new ModuleSummary + { + key = grp.Key, + source = grp.First(), + count = grp.Count() + }) + .OrderBy(grp => grp.source.sourcefile).ThenBy(grp => grp.source.line).ThenBy(grp => grp.source.type).ToList(); + } + + object ToDump() => new + { + Info = new + { + name, + score = score.ToString().PadLeft(3), + totalNumberOfFlaws = totalNumberOfFlaws.ToString().PadLeft(5), + numberOfImportantFlaws = numberOfImportantFlaws.ToString().PadLeft(5) + }, + summary, + flaws = flawList + }; +} + +internal class ModuleSummary +{ + public string key { get; set; } + public ModuleFlaw source { get; set; } + public int count { get; set; } +} + +internal class Severity +{ + public string Level => severity.SeverityLabel(); + internal int severity { get; set; } + public int Count { get; set; } + + object ToDump() => new + { + Level, + Count = Count.ToString().PadLeft(4) + }; +} + +internal class ModuleFlaw +{ + public string type { get; set; } + internal string sourcefile { get; set; } + public string path => string.IsNullOrEmpty(sourcefile) ? "n/a" : System.IO.Path.GetDirectoryName(sourcefile); + public string file => string.IsNullOrEmpty(sourcefile) ? "n/a" : System.IO.Path.GetFileName(sourcefile); + public int count { get; set; } + public int line { get; set; } + public int issueid { get; set; } + public int severity { get; set; } + public int cweid { get; set; } + public string cwename { get; set; } + public string remediation_status{ get; set; } + public int categoryid { get; set; } + public bool hasMitigations { get; set; } + + public ModuleFlaw(XElement element) + { + var cwe = element.Ancestors().Where(e => e.Name.LocalName == "cwe").LastOrDefault(); + cwename = cwe.Attribute("cwename")?.Value ?? ""; + hasMitigations = element.Descendants().Any(sfd => sfd.Name.LocalName == "mitigations"); + var regex = new Regex(@"\.!newinit_0_[0-9]|mscorlib_dll|system_xml_dll|system_web_dll|system_data_dll|system_directoryservices_dll|system_dll\."); + type = regex.Replace(element.Attribute("type")?.Value, "").Trim(new[] { '.' }); + sourcefile = System.IO.Path.Combine((element.Attribute("sourcefilepath")?.Value ?? "").Replace("/jazz new", ""), + element.Attribute("sourcefile")?.Value ?? ""); + remediation_status = element.Attribute("remediation_status")?.Value ?? ""; + line = Convert.ToInt32(element.Attribute("line")?.Value ?? "0"); + count = Convert.ToInt32(element.Attribute("count")?.Value ?? "0"); + issueid = Convert.ToInt32(element.Attribute("issueid")?.Value ?? "0"); + severity = Convert.ToInt32(element.Attribute("severity")?.Value ?? "0"); + cweid = Convert.ToInt32(element.Attribute("cweid")?.Value ?? "0"); + categoryid = Convert.ToInt32(element.Attribute("categoryid")?.Value ?? "0"); + } + + public ModuleFlaw(Flaw flaw) + { + hasMitigations = flaw.hasMitigations; + type = flaw.type; + sourcefile = flaw.sourcefile; + line = flaw.line; + } + + object ToDump() => new + { + categoryid = categoryid.ToString().PadLeft(5), + cweid = cweid.ToString().PadLeft(5), + hasMitigations, + type, + path, + file, + line = line.ToString().PadLeft(5), + count = count.ToString().PadLeft(5), + issueid = issueid.ToString().PadLeft(5), + severity = severity.SeverityLabel() + }; + +} + +internal class Flaw : ModuleFlaw +{ + public string module { get; set; } + public string description { get; set; } + + public Flaw(XElement element) + : base(element) + { + module = string.Join("\r\n", element.Attribute("module")?.Value.Split("/".ToCharArray())); + description = element.Attribute("description")?.Value; + } + + object ToDump() => new + { + Info = new + { + categoryid = $"{categoryid.CategoryLabel()} ({categoryid})", + cweid = cweid.ToString().PadLeft(5), + cwename, + hasMitigations, + type, + path, + file, + line = line.ToString().PadLeft(5), + count = count.ToString().PadLeft(5), + issueid = issueid.ToString().PadLeft(5), + severity = severity.SeverityLabel() + }, + description + }; +} + +internal class Cwe +{ + public int id { get; set; } + public string category { get; set; } + public string name { get; set; } + public int severity { get; set; } + public int count { get; set; } + public string recommendation { get; set; } + public IEnumerable details { get; set; } + + public Cwe(XElement module) + { + var categoryElement = module.Parent; + var severityElement = categoryElement.Parent; + severity = Convert.ToInt32(severityElement.Attribute("level")?.Value ?? "0"); + + category = categoryElement.Attribute("categoryname")?.Value ?? ""; + var recommendations = categoryElement.Descendants().Where(d => d.Name.LocalName == "recommendations"); + var content = recommendations.Descendants(); + recommendation = string.Join("\r\n", content.ToList().Select(n => (n.Name.LocalName == "bulletitem" ? "- " : "") + n.Attribute("text")?.Value)); + + id = Convert.ToInt32(module.Attribute("cweid").Value); + name = module.Attribute("cwename").Value; + + var staticFlaws = module.XPathSelectElements("./*").Where(m => m.Name.LocalName == "staticflaws"); + var flaws = (staticFlaws.SelectMany(m => m.XPathSelectElements("./*").Where(sf => sf.Name.LocalName == "flaw")))?.ToList() + .Select(f => new Flaw(f)) + .GroupBy(grp => new { grp.module, grp.type, grp.description }) + .Select(x => x.First()); + + details = flaws + .Where(f => !f.hasMitigations) + .OrderBy(d => d.type).ThenBy(d => d.module).ThenBy(d => d.description); + + count = details.Count(); + } + + object ToDump() => new + { + Info = new + { + Name = name, + Category = $"{category} ({id})", + Severity = severity.SeverityLabel(), + wo_Tests = count + }, + recommendation + + }; +} \ No newline at end of file diff --git a/Veracode/Veracode Module Analytics.linq b/Veracode/Veracode Module Analytics.linq new file mode 100644 index 0000000..1c3c1ed --- /dev/null +++ b/Veracode/Veracode Module Analytics.linq @@ -0,0 +1,293 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +//private string xmlAnalyticsFile = @"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Jazz_web_201911511115217.xml"; +private string xmlAnalyticsFile = @"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Strata_Jazz_Web_201953102954843.xml"; + +public static class IntExtensions +{ + public static string SeverityLabel(this int severity) + { + switch (severity) + { + case 5: return "Very High"; + case 4: return "High"; + case 3: return "Medium"; + case 2: return "Low"; + case 1: return "Very Low"; + default: return "Informational"; + } + } +} + +internal class Module +{ + public string name { get; set; } + public int score { get; set; } + public int totalNumberOfFlaws => flawsBySeverity.Values.Sum(); + public int numberOfImportantFlaws => flawsBySeverity.Where(f => f.Key > 2).Select(f => f.Value).Sum(); + private Dictionary flawsBySeverity { get; set; } + public string flawsSummary => totalNumberOfFlaws > 0 + ? flawsBySeverity.Where(f => f.Value > 0).OrderByDescending(f => f.Key).Aggregate(new StringBuilder("Severity\n"), (x, y) => + x.Append($"{y.Key.SeverityLabel()}: {y.Value}\r\n")).ToString().TrimEnd(new[] { '\r', '\n' }) + : ""; + public IEnumerable flaws { get; set; } + public string flawList => !flaws.Any() + ? "" : flaws.Aggregate(new StringBuilder("path\tfile\tline\ttype\n"), (x, y) => + x.AppendLine($"{(string.IsNullOrEmpty(y.sourcefile) ? "na" : Path.GetDirectoryName(y.sourcefile))}\t" + + $"{(string.IsNullOrEmpty(y.sourcefile) ? "na" : Path.GetFileName(y.sourcefile))}\t{y.line}\t{y.type}")).ToString(); + + public Module(XElement module, IEnumerable cwes) + { + name = module.Attribute("name")?.Value; + score = Convert.ToInt32(module.Attribute("score")?.Value ?? "0"); + flawsBySeverity = new Dictionary(); + flawsBySeverity[0] = Convert.ToInt32(module.Attribute("numflawssev0")?.Value ?? "0"); + flawsBySeverity[1] = Convert.ToInt32(module.Attribute("numflawssev1")?.Value ?? "0"); + flawsBySeverity[2] = Convert.ToInt32(module.Attribute("numflawssev2")?.Value ?? "0"); + flawsBySeverity[3] = Convert.ToInt32(module.Attribute("numflawssev3")?.Value ?? "0"); + flawsBySeverity[4] = Convert.ToInt32(module.Attribute("numflawssev4")?.Value ?? "0"); + flawsBySeverity[5] = Convert.ToInt32(module.Attribute("numflawssev5")?.Value ?? "0"); + var cx = cwes.Where(c => c.details.Any(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase))); + flaws = cx.SelectMany(c => c.details.Where(d => d.module.Equals(name, StringComparison.CurrentCultureIgnoreCase)) + .Select(d => new ModuleFlaw(d))) + //.GroupBy(d => $"{d.type}{d.sourcefile}{d.line}").Select(grp => grp.First()) + .OrderBy(grp => grp.sourcefile).ThenBy(grp => grp.line).ThenBy(grp => grp.type); + } +} + +internal class ModuleFlaw +{ + public string type { get; set; } + public string sourcefile { get; set; } + public int line { get; set; } + public bool hasMitigations { get; set; } + + public ModuleFlaw(XElement element) + { + hasMitigations = element.Descendants().Any(sfd => sfd.Name.LocalName == "mitigations"); + var regex = new Regex(@"\.!newinit_0_[0-9]|mscorlib_dll|system_xml_dll|system_web_dll|system_data_dll|system_directoryservices_dll|system_dll\."); + type = regex.Replace(element.Attribute("type")?.Value, "").Trim(new[] { '.' }); + sourcefile = System.IO.Path.Combine((element.Attribute("sourcefilepath")?.Value ?? "").Replace("/jazz new", ""), + element.Attribute("sourcefile")?.Value ?? ""); + line = Convert.ToInt32(element.Attribute("line")?.Value ?? "0"); + } + + public ModuleFlaw(Flaw flaw) + { + hasMitigations = flaw.hasMitigations; + type = flaw.type; + sourcefile = flaw.sourcefile; + line = flaw.line; + } +} + +internal class Flaw : ModuleFlaw +{ + public string module { get; set; } + public string description { get; set; } + public string grace_period_expires { get; set; } + public string remediation_status { get; set; } + public bool remediated => (remediation_status == "Fixed"); + + public Flaw(XElement element) + : base(element) + { + module = string.Join("\r\n", element.Attribute("module")?.Value.Split("/".ToCharArray())); + description = element.Attribute("description")?.Value; + DateTime parsedDate; + var theDate = System.Net.WebUtility.HtmlDecode(element.Attribute("grace_period_expires")?.Value).Replace(" UTC", "Z"); + if (DateTime.TryParse(theDate, out parsedDate)) + { + grace_period_expires = parsedDate.ToShortDateString(); + } + else + { + grace_period_expires = string.Empty; + } + remediation_status = element.Attribute("remediation_status")?.Value; + } + +} + +internal class Cwe +{ + public int id { get; set; } + public string category { get; set; } + public string name { get; set; } + public int severity { get; set; } + public int count { get; set; } + public string recommendation { get; set; } + public IEnumerable details { get; set; } + + public Cwe(XElement module) + { + var categoryElement = module.Parent; + var severityElement = categoryElement.Parent; + severity = Convert.ToInt32(severityElement.Attribute("level")?.Value ?? "0"); + + category = categoryElement.Attribute("categoryname")?.Value ?? ""; + var recommendations = categoryElement.Descendants().Where(d => d.Name.LocalName == "recommendations"); + var content = recommendations.Descendants(); + recommendation = string.Join("\r\n", content.ToList().Select(n => (n.Name.LocalName == "bulletitem" ? "- " : "") + n.Attribute("text")?.Value)); + + id = Convert.ToInt32(module.Attribute("cweid").Value); + name = module.Attribute("cwename").Value; + + var staticFlaws = module.XPathSelectElements("./*").Where(m => m.Name.LocalName == "staticflaws"); + var flaws = (staticFlaws.SelectMany(m => m.XPathSelectElements("./*").Where(sf => sf.Name.LocalName == "flaw")))?.ToList() + .Select(f => new Flaw(f)); + //.GroupBy(grp => new { grp.module, grp.type, grp.description }) + //.Select(x => x.First()); + + details = flaws + //.Where(f => !f.hasMitigations) + .OrderBy(d => d.type).ThenBy(d => d.module).ThenBy(d => d.description); + + count = details.Count(); + } +} + +internal IEnumerable ParseVeracodeReport(XDocument xmlDoc) +{ + return from module in xmlDoc.Descendants() + where module.Name.LocalName == "cwe" + && module.Attributes().Any(a => a.Name == "cweid") + orderby Int32.Parse(module.Attribute("cweid").Value) + select new Cwe(module); +} + +void Main() +{ + XDocument xmlDoc = XDocument.Load(xmlAnalyticsFile); + //xmlDoc.DumpFormatted(); + var cwes = ParseVeracodeReport(xmlDoc).Where(cwe => cwe.count > 0); + cwes + .SelectMany(c => c.details.Select(d => new + { + c.severity, + c.category, + c.id, + c.name, + d.type, + d.sourcefile, + line = d.line.ToString(), + d.hasMitigations, + d.module, + d.grace_period_expires, + d.remediation_status, + d.remediated + })) + .Where(c => !c.remediated) + .OrderByDescending(c => c.severity).ThenBy(c => c.category).ThenBy(c => c.module).ThenBy(c => c.sourcefile).ThenBy(c => c.type).ThenBy(c => c.line) + .GroupBy(c => new + { + Severity = c.severity.SeverityLabel(), + Category = c.category, + CWE_Id = c.id.ToString(), + Description = c.name + }, (key, group) => new + { + Severity = key, + Items = group.ToList().Select(g => new + { + g.type, + g.sourcefile, + g.line, + g.hasMitigations, + g.module, + g.grace_period_expires + }) + }) + .Dump(); + // cwes.SelectMany(c => c.details.Select(d => new { c.category, c.name, d.type, d.sourcefile, line = d.line.ToString(), d.hasMitigations, d.module })) + // .Where(c => c.module.Contains(".dss.")) + // .OrderBy(c => c.module).ThenBy(c => c.category).ThenBy(c => c.sourcefile).ThenBy(c => c.type).ThenBy(c => c.line) + // .Dump(); + // cwes.Where(cwe => cwe.count > 1) + // .OrderByDescending(cwe => cwe.severity).ThenByDescending(cwe => cwe.count) + // .Select(cwe => new + // { + // severity = cwe.severity.SeverityLabel(), + // category_id = $"{cwe.category} ({cwe.id})", + // wo_Tests = cwe.count, + // cwe.name, + // cwe.recommendation }) + // .Dump($"Summary: ({cwes.Where(cwe => cwe.count > 1).Count()})"); + // + // var regex = new Regex(@"\.Test\.|\.IntegrationTests\.|\.UnitTests\."); + // var modules = from m in xmlDoc.Descendants() + // where m.Name.LocalName == "module" && m.Parent.Name.LocalName == "modules" + // select new Module(m, cwes); + // modules.Where(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0) + // .Select(m => new {m.name, m.score, m.totalNumberOfFlaws, m.numberOfImportantFlaws, m.flawsSummary, m.flawList}) + // .Dump($"Modules: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})"); + // + // modules.Where(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0 + // && new [] {"Strata.CS.Jazz.Biz.DSS.Episodes.EpisodeDefinition.dll","Strata.CS.Jazz.Biz.DSS.Episodes.dll","Strata.Administrator.Base.dll"}.Contains(m.name)) + // .Select(m => new { m.name, m.flaws }) + // .Dump($"Module Flaws: ({modules.Count(m => !regex.IsMatch(m.name) && m.totalNumberOfFlaws > 0)})"); + // + // cwes.Where(cwe => cwe.count > 1) + // .OrderBy(cwe => cwe.id).ToList() + // .ForEach(cwe => cwe.details.Dump($"ID: {cwe.id} {cwe.name} ({cwe.count})")); + // //JsonConvert.SerializeObject(cwes, Newtonsoft.Json.Formatting.Indented).Dump("Json"); +} \ No newline at end of file diff --git a/Veracode/Veracode Solution Manager.linq b/Veracode/Veracode Solution Manager.linq new file mode 100644 index 0000000..f93d148 --- /dev/null +++ b/Veracode/Veracode Solution Manager.linq @@ -0,0 +1,80 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var regex = new Regex("^Project[^=]+= ([^,]+), \"([^\"]+).+$"); +var veracode = File.ReadAllLines(@"C:\git\jazz\jazz web.sln") + .Where(x => x.StartsWith("Project")) + .Select(x => regex.Matches(x)?[0].Groups[1]?.Value); + +//File.ReadAllLines(@"C:\git\jazz\jazz build all.sln") +// .Where(x => x.StartsWith("Project")).Dump(); + +var solution = File.ReadAllLines(@"C:\git\jazz\jazz build all.sln") + .Where(x => x.StartsWith("Project")) + .Select(x => new + { + name = regex.Matches(x)?[0].Groups[1]?.Value.Trim('"'), + project = regex.Matches(x)?[0].Groups[2]?.Value + }) + .Where(x => !veracode.Contains(x.project)) + .Where(x => !x.project.StartsWith("Test") && !x.project.StartsWith("Internal Tools")) + .OrderBy(x => x.name); +solution.Dump(); \ No newline at end of file diff --git a/Veracode/Veracode parsing report for the modules.linq b/Veracode/Veracode parsing report for the modules.linq new file mode 100644 index 0000000..128e2df --- /dev/null +++ b/Veracode/Veracode parsing report for the modules.linq @@ -0,0 +1,74 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +XDocument xmlDoc = XDocument.Load(@"C:\Users\tlamb\Downloads\detailedreport_Strata_Jazz_Web_Jazz_web_201911511115217.xml"); + xmlDoc.DumpFormatted(); + xmlDoc.XPathSelectElements("./detailedreport/severity/category/cwe").Dump(); + + var rows = from row in xmlDoc.XPathSelectElements("//node()[local-name(.) = 'module']") select row; + var modules = rows.SelectMany(row => row.Attributes().Where(a => a.Name == "name").Select(a => a.Value)); + + //modules.Distinct().OrderBy(m => m).Dump(); + + var cwerows = from row in xmlDoc.XPathSelectElements("//node()[local-name(.) = 'cwe']") select row; + var cwes = cwerows.SelectMany(c => c.Attributes().Where(a => a.Name == "cweid" && a.Value == "73").Select(a => a.Parent)); + + cwes.Dump(); \ No newline at end of file diff --git a/Working with Reports SortArgs.linq b/Working with Reports SortArgs.linq new file mode 100644 index 0000000..f1e044d --- /dev/null +++ b/Working with Reports SortArgs.linq @@ -0,0 +1,87 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var reportGUIDs = new Guid[] { + new Guid("e06ef5e3-102d-4563-8e22-9c3ecbf6e671"), + new Guid("d0a5c9dc-c5d7-4a0b-a0f9-282735a44782"), + new Guid("b2575e8d-24bf-4f19-90c4-233d26a705d0"), + new Guid("28aa8af2-d21b-4307-85f0-cf7906363742") +}; +(from report in REReports + where reportGUIDs.Contains(report.ReportGUID) + select new + { + Report = report, + Setup = (from s in REDSCubeReportSetups + where s.ReportGUID == report.ReportGUID + select new + { + s.DSCubeReportSetupGUID, + s.ReportGUID, + s.LaunchMode, + s.IsDrilldownIndented, + s.Style, + s.IsAutoRefresh, + SortArgs = s.SortArgsXML.XMLToJson(Newtonsoft.Json.Formatting.Indented), + }), + DataSources = (from ds in REDSCubeReportDataSourceLinks where ds.ReportGUID == report.ReportGUID select ds) + + }).Dump(); \ No newline at end of file diff --git a/archive_pagelogs for reports homr.linq b/archive_pagelogs for reports homr.linq new file mode 100644 index 0000000..c468ef3 --- /dev/null +++ b/archive_pagelogs for reports homr.linq @@ -0,0 +1,68 @@ + + + 4f885e7e-d8bb-427c-a54e-8e3e1c3137a7 + true + IOAK-SQL-LOG-01.sdt.local + jazz log prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +(from pl in Archive_PageLogs +where pl.Url.StartsWith("/cci/Reports/Home.aspx") + && pl.DateTimeStamp > new DateTime(2020, 1, 1) +select pl) +.GroupBy(pl => pl.DatabaseName, (g, d) => new {d.First().DatabaseName, Count = d.Count()}) +.OrderBy(pl => pl.DatabaseName) +.Dump(); \ No newline at end of file diff --git a/cci tables.linq b/cci tables.linq new file mode 100644 index 0000000..f012730 --- /dev/null +++ b/cci tables.linq @@ -0,0 +1,121 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +var important = new[] { +"CaseTypeEntity", +"CaseTypeFamilyMetrics", +"ChargeCaptureMetricGoal", +"ChargeCodeConfig", +"ChargeCodeCostDetail", +"ClinicalGrowthMetricGoal", +"Configuration", +"CustomOppMetricLink", +"CustomOpportunity", +"DepartmentPatientADT", +"DepartmentPatientCensus", +"DepartmentPatientDailyCensus", +"DepartmentPatientHourlyADTCensus", +"DepartmentPatientHourlyCensus", +"DepartmentStaffHourlyCensus", +"DirectCostMetricGoal", +"EmployeeWorkedHours", +"FactMetric", +"FactOpportunityMetric", +"FactOpportunitySavings", +"FreeFormInitiativeTrackingData", +"FreeFormOpportunity", +"GLDepartment", +"GLOpportunity", +"Initiative", +"InitiativeComment", +"InitiativeCriteria", +"InitiativeScore", +"InitiativeWorkflowHistory", +"FactPatientEncounterSummary", +"VariationEncounterSaving", +"VariationEncounterSavingInfo"}; +var tables = ExecuteQueryDynamic(@"SELECT c.TABLE_NAME, + c.COLUMN_NAME, + c.ORDINAL_POSITION, + c.DATA_TYPE, + CASE c.IS_NULLABLE WHEN 'no' THEN 'not null' ELSE '' END [Nullability], + CASE WHEN c.COLUMN_DEFAULT IS NULL THEN '' ELSE c.COLUMN_DEFAULT END COLUMN_DEFAULT +FROM INFORMATION_SCHEMA.COLUMNS AS c +INNER JOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_NAME = t.TABLE_NAME AND t.TABLE_TYPE = 'BASE TABLE' +WHERE c.TABLE_SCHEMA = 'cci' AND c.TABLE_CATALOG = 'jazz dev master Prod' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION") +.Select(t => new +{ + table = t.TABLE_NAME as string, + column = t.COLUMN_NAME as string, + position = t.ORDINAL_POSITION as int?, + dataType = t.DATA_TYPE as string, + nullability = t.Nullability as string, + columnDefault = t.COLUMN_DEFAULT as string +}).ToList(); +tables +.Where(t => !important.Contains(t.table)) +.GroupBy(t => t.table, (g, d) => d.OrderBy(c => c.position)) +.ToList() +.ForEach(x => +{ + x.Select(t => new { t.column, t.dataType, t.nullability, t.columnDefault }).Dump(x.First().table); +}); \ No newline at end of file diff --git a/consolidate CaseTypeFamily information.linq b/consolidate CaseTypeFamily information.linq new file mode 100644 index 0000000..d825f46 --- /dev/null +++ b/consolidate CaseTypeFamily information.linq @@ -0,0 +1,398 @@ + + + 580b3b8d-cc02-4a68-8fbd-d1ec374a25f2 + true + D0001-sql-11.sdt.local + jazz dev master Prod + true + + AWSSDK.DynamoDBv2 + AWSSDK.S3 + Newtonsoft.Json + Amazon.DynamoDBv2.DataModel + Amazon.DynamoDBv2 + Amazon.DynamoDBv2.DocumentModel + Amazon.DynamoDBv2.Model + + +public static Dictionary> Versions = new Dictionary>(); + +void Main() +{ + Versions = (from v in CaseTypeFamilyVersions select v) + .ToDictionary(v => v.CaseTypeFamilyVersionID, t => new Tuple(t.StartDate, t.EndDate)); + var aprdrg = (from aprDto in CaseTypeFamilyMappingAPRDRGs + join ctfDto in CaseTypeFamilies on aprDto.CaseTypeFamilyID equals ctfDto.CaseTypeFamilyID + select new AllCaseTypeFamily( + ctfDto.CaseTypeFamilyID, + ctfDto.CaseTypeFamilyGUID, + ctfDto.Name, + ctfDto.CaseTypeFamilyGlobalID, + aprDto.APRDRGCode, + aprDto.CaseTypeFamilyVersionID)).ToList(); + var msdrg = (from icd10Dto in CaseTypeFamilyMappingICD10s + join ctfDto in CaseTypeFamilies on icd10Dto.CaseTypeFamilyID equals ctfDto.CaseTypeFamilyID + select new AllCaseTypeFamily( + ctfDto.CaseTypeFamilyID, + ctfDto.CaseTypeFamilyGUID, + ctfDto.Name, + ctfDto.CaseTypeFamilyGlobalID, + icd10Dto.SkipICD, + icd10Dto.ICD10Code, + icd10Dto.MSDRGCode, + icd10Dto.CaseTypeFamilyVersionID)).ToList(); + var cpt = (from cptDto in CaseTypeFamilyMappingCPTs + join ctfDto in CaseTypeFamilies on cptDto.CaseTypeFamilyID equals ctfDto.CaseTypeFamilyID + select new AllCaseTypeFamily( + ctfDto.CaseTypeFamilyID, + ctfDto.CaseTypeFamilyGUID, + ctfDto.Name, + ctfDto.CaseTypeFamilyGlobalID, + cptDto.CaseTypeFamilyVersionID, + cptDto.CPTCode)).ToList(); + //cpt.Dump(nameof(cpt)); + var allCaseTypeFamily = aprdrg.Union(msdrg).Union(cpt) + .OrderBy(x => x.CaseTypeFamilyID) + .ThenByDescending(x => x.CaseTypeFamilyVersionID); + var globalCaseTypeFamily = allCaseTypeFamily + .GroupBy(ctf => new { ctf.CaseTypeFamilyID, ctf.CaseTypeFamilyGUID, ctf.Name, ctf.CaseTypeFamilyGlobalID, ctf.CaseTypeFamilyVersionID }, + (g, d) => new GlobalCaseTypeFamily( + g.CaseTypeFamilyID, + g.CaseTypeFamilyGUID, + g.Name, + g.CaseTypeFamilyGlobalID, + g.CaseTypeFamilyVersionID, + d.First().StartDate, + d.First().EndDate, + d.Where(x => !string.IsNullOrEmpty(x.APRDRGCode)).Select(x => x.APRDRGCode), + d.Where(x => !string.IsNullOrEmpty(x.CPTCode)).Select(x => x.CPTCode), + d + .Where(x => (string.IsNullOrEmpty(x.APRDRGCode) || string.IsNullOrEmpty(x.CPTCode)) && !x.SkipICD) + .Select(x => new ICD10Code(x.ICD10Code, x.MSDRGCode)), + d + .Where(x => (string.IsNullOrEmpty(x.APRDRGCode) || string.IsNullOrEmpty(x.CPTCode)) && x.SkipICD) + .Select(x => new ICD10Code(x.ICD10Code, x.MSDRGCode)) + )); + globalCaseTypeFamily.Dump(); +/* + try + { + var config = new AmazonDynamoDBConfig + { + ServiceURL = "http://localhost:8000" + }; + var client = new AmazonDynamoDBClient(config); + var context = new DynamoDBContext(client); + DeleteTable(client, nameof(GlobalCaseTypeFamily)); + CreateTableGlobalCaseTypeFamily(client); + var table = Amazon.DynamoDBv2.DocumentModel.Table.LoadTable(client, nameof(GlobalCaseTypeFamily)); + globalCaseTypeFamily.ToList() + .ForEach(ctf => + { + table.PutItem(Document.FromJson(JsonConvert.SerializeObject(ctf))); + }); + } + catch (Exception ex) + { + ex.Dump(); + throw; + } + */ + //var result = JsonConvert.SerializeObject(globalCaseTypeFamily); + //result.Dump(nameof(globalCaseTypeFamily)); + + // Util.WriteCsv(result, @"D:\CaseTypeFamily.csv"); + //System.IO.File.WriteAllText(@"D:\CaseTypeFamily.json", JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented)); +} + +private static void CreateTableGlobalCaseTypeFamily(AmazonDynamoDBClient client) +{ + string tableName = nameof(GlobalCaseTypeFamily); + var response = client.CreateTable(new CreateTableRequest + { + TableName = tableName, + AttributeDefinitions = new List() + { + new AttributeDefinition + { + AttributeName = "PartitionKey", + AttributeType = "S" + }, + new AttributeDefinition + { + AttributeName = "CaseTypeFamilyID", + AttributeType = "N" + }, + new AttributeDefinition + { + AttributeName = "CaseTypeFamilyGUID", + AttributeType = "S" + }, + new AttributeDefinition + { + AttributeName = "Name", + AttributeType = "S" + }, + new AttributeDefinition + { + AttributeName = "CaseTypeFamilyGlobalID", + AttributeType = "S" + } + }, + KeySchema = new List() + { + new KeySchemaElement() + { + AttributeName = "PartitionKey", + KeyType = "HASH" + }, + new KeySchemaElement + { + AttributeName = "CaseTypeFamilyID", + KeyType = "RANGE" + } + } + }); + WaitTillTableCreated(client, tableName, response); +} + +#region AWS DynamoDB Helpers + +private static void DeleteTable(AmazonDynamoDBClient client, string tableName) +{ + try + { + var deleteTableResponse = client.DeleteTable(new DeleteTableRequest() + { + TableName = tableName + }); + WaitTillTableDeleted(client, tableName, deleteTableResponse); + } + catch (ResourceNotFoundException) + { + // There is no such table. + } +} + +private static void WaitTillTableCreated(AmazonDynamoDBClient client, string tableName, + CreateTableResponse response) +{ + var tableDescription = response.TableDescription; + + string status = tableDescription.TableStatus; + + Console.WriteLine(tableName + " - " + status); + + // Let us wait until table is created. Call DescribeTable. + while (status != "ACTIVE") + { + System.Threading.Thread.Sleep(5000); // Wait 5 seconds. + try + { + var res = client.DescribeTable(new DescribeTableRequest + { + TableName = tableName + }); + Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, + res.Table.TableStatus); + status = res.Table.TableStatus; + } + // Try-catch to handle potential eventual-consistency issue. + catch (ResourceNotFoundException) + { } + } +} + +private static void WaitTillTableDeleted(AmazonDynamoDBClient client, string tableName, + DeleteTableResponse response) +{ + var tableDescription = response.TableDescription; + + string status = tableDescription.TableStatus; + + Console.WriteLine(tableName + " - " + status); + + // Let us wait until table is created. Call DescribeTable + try + { + while (status == "DELETING") + { + System.Threading.Thread.Sleep(5000); // wait 5 seconds + + var res = client.DescribeTable(new DescribeTableRequest + { + TableName = tableName + }); + Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, + res.Table.TableStatus); + status = res.Table.TableStatus; + } + } + catch (ResourceNotFoundException) + { + // Table deleted. + } +} + +#endregion + +public class ICD10Code +{ + [DynamoDBProperty] + public string ICD10_Code { get; set; } + [DynamoDBProperty] + public string MSDRGCode { get; set; } + + public ICD10Code() + { + ICD10_Code = string.Empty; + MSDRGCode = string.Empty; + } + + public ICD10Code(string icd10code, string msdrgcode) + { + ICD10_Code = icd10code; + MSDRGCode = msdrgcode; + } +} + +[DynamoDBTable("GlobalCaseTypeFamily")] +public class GlobalCaseTypeFamily +{ + [DynamoDBHashKey] + public string PartitionKey => $"{CaseTypeFamilyVersionID}|{CaseTypeFamilyID}"; + [DynamoDBProperty] + public int CaseTypeFamilyID { get; set; } + [DynamoDBProperty] + public Guid CaseTypeFamilyGUID { get; set; } + [DynamoDBProperty] + public string Name { get; set; } + [DynamoDBProperty] + public string CaseTypeFamilyGlobalID { get; set; } + [DynamoDBProperty] + public int CaseTypeFamilyVersionID { get; set; } + [DynamoDBProperty] + public DateTime StartDate { get; set; } + [DynamoDBProperty] + public DateTime EndDate { get; set; } + [DynamoDBProperty] + public List APRDRGCodes { get; set; } + [DynamoDBProperty] + public List CPTCodes { get; set; } + [DynamoDBProperty] + public List ICD10Codes { get; set; } + [DynamoDBProperty] + public List SkipICD10Codes { get; set; } + + public GlobalCaseTypeFamily() + { + CaseTypeFamilyID = -1; + CaseTypeFamilyGUID = Guid.Empty; + Name = string.Empty; + CaseTypeFamilyGlobalID = string.Empty; + CaseTypeFamilyVersionID = -1; + StartDate = DateTime.MinValue; + EndDate = DateTime.MaxValue; + APRDRGCodes = new List(); + CPTCodes = new List(); + } + + public GlobalCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, int caseTypeFamilyVersionID, + DateTime startDate, DateTime endDate) + { + CaseTypeFamilyID = caseTypeFamilyID; + CaseTypeFamilyGUID = caseTypeFamilyGuid; + Name = name; + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + CaseTypeFamilyVersionID = caseTypeFamilyVersionID; + StartDate = startDate; + EndDate = endDate; + } + + public GlobalCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, int caseTypeFamilyVersionID, + DateTime startDate, DateTime endDate, + IEnumerable aprdrgcodes, + IEnumerable cptcodes, + IEnumerable icd10codes, + IEnumerable skipicd10codes) + : this(caseTypeFamilyID, caseTypeFamilyGuid, name, caseTypeFamilyGlobalID, caseTypeFamilyVersionID, startDate, endDate) + { + APRDRGCodes = aprdrgcodes.ToList(); + CPTCodes = cptcodes.ToList(); + ICD10Codes = icd10codes.ToList(); + SkipICD10Codes = skipicd10codes.ToList(); + } +} + +public class AllCaseTypeFamily +{ + public int CaseTypeFamilyID { get; set; } + public Guid CaseTypeFamilyGUID { get; set; } + public string Name { get; set; } + public string CaseTypeFamilyGlobalID { get; set; } + public string APRDRGCode { get; set; } + public bool SkipICD { get; set; } + public string ICD10Code { get; set; } + public string MSDRGCode { get; set; } + public string CPTCode { get; set; } + public int CaseTypeFamilyVersionID { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + + public AllCaseTypeFamily() + { + CaseTypeFamilyID = -1; + CaseTypeFamilyGUID = Guid.Empty; + Name = string.Empty; + CaseTypeFamilyGlobalID = string.Empty; + APRDRGCode = string.Empty; + SkipICD = false; + ICD10Code = string.Empty; + MSDRGCode = string.Empty; + CPTCode = string.Empty; + CaseTypeFamilyVersionID = -1; + StartDate = DateTime.MinValue; + EndDate = DateTime.MaxValue; + } + + public AllCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID) + : this() + { + CaseTypeFamilyID = caseTypeFamilyID; + CaseTypeFamilyGUID = caseTypeFamilyGuid; + Name = name; + CaseTypeFamilyGlobalID = caseTypeFamilyGlobalID; + } + + public AllCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, int caseTypeFamilyVersionID) + : this(caseTypeFamilyID, caseTypeFamilyGuid, name, caseTypeFamilyGlobalID) + { + CaseTypeFamilyVersionID = caseTypeFamilyVersionID; + if (Versions.ContainsKey(caseTypeFamilyVersionID)) + { + StartDate = UserQuery.Versions[caseTypeFamilyVersionID].Item1; + EndDate = UserQuery.Versions[caseTypeFamilyVersionID].Item2; + } + } + + public AllCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, string aprdrgCode, int caseTypeFamilyVersionID) + : this(caseTypeFamilyID, caseTypeFamilyGuid, name, caseTypeFamilyGlobalID, caseTypeFamilyVersionID) + { + APRDRGCode = aprdrgCode; + } + + public AllCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, bool skipICD, string icd10Code, string msdrgCode, int caseTypeFamilyVersionID) + : this(caseTypeFamilyID, caseTypeFamilyGuid, name, caseTypeFamilyGlobalID, caseTypeFamilyVersionID) + { + SkipICD = skipICD; + ICD10Code = icd10Code; + MSDRGCode = msdrgCode; + } + + public AllCaseTypeFamily(int caseTypeFamilyID, Guid caseTypeFamilyGuid, string name, string caseTypeFamilyGlobalID, int caseTypeFamilyVersionID, string cptCode) + : this(caseTypeFamilyID, caseTypeFamilyGuid, name, caseTypeFamilyGlobalID, caseTypeFamilyVersionID) + { + CPTCode = cptCode; + } + +} \ No newline at end of file diff --git a/create StrataSphere Mappings.linq b/create StrataSphere Mappings.linq new file mode 100644 index 0000000..9ba35e2 --- /dev/null +++ b/create StrataSphere Mappings.linq @@ -0,0 +1,107 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +//var reports = from report in REReports select report; +//reports.Dump(); + +var parms = from report in REReports +join module in Folders on report.FolderGUID equals module.FolderGuid into reportModules +from rptModule in reportModules.DefaultIfEmpty() + join setup in REDSCubeReportSetups on report.ReportGUID equals setup.ReportGUID + join parameter in REDSCubeReportParameters on report.ReportGUID equals parameter.ReportGUID + where parameter.Name == "Patient Populations" && parameter.ParameterXML != null && parameter.ParameterXML != "" + select new + { + reportName = report.Name, + module = rptModule.Name, + //parameterName = parameter.Name, + //parameter.ColumnName, + parameterXML = XDocument.Parse(parameter.ParameterXML).Descendants("{http://schemas.datacontract.org/2004/07/Strata.CS.Jazz.Biz.Reporting.Parameters}DSCubeSearchCondition"), + Value = XDocument.Parse(parameter.ParameterXML).Descendants("{http://schemas.datacontract.org/2004/07/Strata.CS.Jazz.Biz.Reporting.Parameters}Value"), + ValueIds = XDocument.Parse(parameter.ParameterXML).Descendants("{http://schemas.datacontract.org/2004/07/Strata.CS.Jazz.Biz.Reporting.Parameters}ValueIDArray") + }; +parms.ToList().Where(p => p.parameterXML.Any()).OrderBy(r => r.reportName) +.Select(p => new +{ + p.reportName, + p.module, + values = p.Value.FirstOrDefault()?.Value.Split(new[] { ',' }).Select(v => v.Trim()), + valueIds = p.ValueIds.Descendants().Select(vi => vi.Value) +}).Dump(); + +var mappings = parms.ToList().Where(p => p.parameterXML.Any()).ToList() +.SelectMany(p => from ci in DimClinicalIndicators + join def in Definitions on ci.Name equals def.Name + where p.ValueIds.Descendants().Select(vi => Regex.Replace(vi.Value, @"[^\d]", "")).ToList().Contains(ci.ClinicalIndicatorID.ToString()) + select new { id = ci.ClinicalIndicatorID, Guid = ci.MemberGUID, name = ci.Name, definitionGuid = def.Id } +).Distinct().OrderBy(p => p.name); +mappings.Dump(); + +var sql = "INSERT INTO dbo.StandardDefinitionMapping ( StandardDefinitionGUID, StandardDefinitionName, StandardDefinitionType, MappingMemberValue )\r\nValues " + string.Join(",\r\n ", +mappings.Select(y => $"('{y.definitionGuid}','[Patient Populations].[Patient Populations].&[{y.id}]','Patient Populations','{y.name}')")); +sql.Dump(); \ No newline at end of file diff --git a/date updates/query1.linq b/date updates/query1.linq new file mode 100644 index 0000000..d278f0d --- /dev/null +++ b/date updates/query1.linq @@ -0,0 +1,16 @@ + + +var startDate = DateTime.Now.Date; +var endOfMonth = startDate.AddMonths(1).AddDays(-1).Date; +endOfMonth.Dump(); +endOfMonth.Subtract(startDate).TotalDays.Dump(); +endOfMonth = endOfMonth.AddMonths(1).AddDays(-1).Date; +endOfMonth.Dump(); +endOfMonth.Subtract(startDate).TotalDays.Dump(); +endOfMonth = endOfMonth.AddMonths(1).AddDays(-1).Date; +endOfMonth.Dump(); +endOfMonth.Subtract(startDate).TotalDays.Dump(); +$"{endOfMonth:d}".Dump(); +endOfMonth.ToShortDateString().Dump(); +$"{endOfMonth}".Dump(); +endOfMonth.ToString().Dump(); \ No newline at end of file diff --git a/date updates/query2.linq b/date updates/query2.linq new file mode 100644 index 0000000..dba8e34 --- /dev/null +++ b/date updates/query2.linq @@ -0,0 +1,63 @@ + + +void Main() +{ + var prefix = "fpes"; + if (prefix != "") prefix += "."; + var baselineEndDate = new DateTime(2018, 4, 1); + Enumerable.Range(0, 12).ToList() + .Aggregate("", (x, y) => + { + var result = $"{x} or\r\n({prefix}FiscalYearID = {FiscalMonth.GetFiscalYearID(baselineEndDate.Month, baselineEndDate.Year)}" + + $" and {prefix}FiscalMonthID = {baselineEndDate.Month})"; + baselineEndDate = baselineEndDate.AddMonths(-1); + return result; + }).Substring(5).Dump(); + + baselineEndDate = new DateTime(2018, 4, 1); + var clause = ""; + Enumerable.Range(0, 12) + .ForEach(i => + { + clause += + $"\r\n({prefix}FiscalYearID = {FiscalMonth.GetFiscalYearID(baselineEndDate.Month, baselineEndDate.Year)} and {prefix}FiscalMonthID = {baselineEndDate.Month}) or "; + baselineEndDate = baselineEndDate.AddMonths(-1); + }); + + clause = clause.Substring(0, clause.Length - 3); + clause.Dump(); +} + +// Define other methods and classes here + +public class FiscalMonth +{ + + public static int GetFiscalYearID(int calendarMonth, int calendarYear) + { + var endMonth = DBSetting.General.FiscalYearEndMonth; + return (calendarMonth <= endMonth ? calendarYear : calendarYear + 1); + } + +} + +public static class DBSetting +{ + public static class General + { + public static int FiscalYearEndMonth => 12; + } +} + +public static class EnumerableExtensions +{ + + public static void ForEach(this IEnumerable enumeration, Action action) + { + foreach (T item in enumeration) + { + action(item); + } + } + +} \ No newline at end of file diff --git a/dynamic query test.linq b/dynamic query test.linq new file mode 100644 index 0000000..c5ecedf --- /dev/null +++ b/dynamic query test.linq @@ -0,0 +1,16 @@ + + + 580b3b8d-cc02-4a68-8fbd-d1ec374a25f2 + true + D0001-sql-11.sdt.local + jazz dev master Prod + true + + System.Linq.Dynamic + + +var query = Configurations +.Where("FiscalYearId != @0", 2020) +.OrderBy("FiscalYearId descending") +.Select("new(Name as config)"); +query.Dump(); \ No newline at end of file diff --git a/mailgun test with template fake.linq b/mailgun test with template fake.linq new file mode 100644 index 0000000..1b744bc --- /dev/null +++ b/mailgun test with template fake.linq @@ -0,0 +1,174 @@ + + + 40766b24-ff74-431b-b387-6c221ede77cf + true + p3121-sql-02.sdt.local + jazz prd UNC 20180206.1 + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + RestSharp + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + RestSharp + RestSharp.Authenticators + + +private static string baseurl = "https://dev.sdt.local/StrataJazz201931"; +private static Random _rnd; + +void Main() +{ +// var now = DateTime.Today.AddDays(-1 * (7 + ((DateTime.Today.DayOfWeek - DayOfWeek.Monday)) % 7)); +// var staffing = new Staffing +// { +// pr = new PayPeriod +// { +// StartDate = now.AddDays(-14), +// EndDate = now.AddDays(-7) +// }, +// Departments = Enumerable.Range(0, 26).ToList() +// .ConvertAll(e => //new Department { department = +// new DeptInfo($"dept_{e}", Random.Next() * 10m, Random.Next() * 10m, Random.Next() * 10m * Random.Next(-1, 1)) +// //} +// ) +// }; +// var data = JsonConvert.SerializeObject(staffing); +// data.Dump(); + SendMessageByTemplateId(@"{""test"":""Low and behold""}").Content.Dump(); +} + +internal static Random Random +{ + get => _rnd ?? (_rnd = new Random()); + set => _rnd = value; +} + +// Define other methods and classes here +public class Staffing +{ + public PayPeriod pr { get; set; } + public List overall => new List { Departments.FirstOrDefault() }; + public List departments => new List + { + new DeptInfo( + $"Current Pay Period ({pr.endDate:M/dd})", + Departments.Sum(d => d.latest_total_variance), + Departments.Sum(d => d.latest_pay_variance), + Departments.Sum(d => d.latest_flex_variance) + ) + }; + internal List Departments { get; set; } +} + +public class PayPeriod +{ + internal DateTime StartDate { get; set; } + internal DateTime EndDate { get; set; } + public string startDate => StartDate.ToString("MM/dd"); + public string endDate => EndDate.ToString("MM/dd"); +} + +public class Department +{ + public DeptInfo department { get; set; } +} + +public class DeptInfo +{ + public string hyperlink => baseurl; + public string name { get; set; } + internal decimal latest_total_variance { get; set; } + internal decimal latest_pay_variance { get; set; } + internal decimal latest_flex_variance { get; set; } + public string total_variance => $"{latest_total_variance:C}"; + public string pay_variance => $"{latest_pay_variance:C}"; + public string flex_variance => $"{latest_flex_variance:C}"; + public string six_month_total_chart => "graph_sparkline_6_pay_period_-1281183930.png"; + public string six_month_pay_chart => "graph_sparkline_6_pay_period_1140344931.png"; + public string six_month_flex_chart => "graph_sparkline_6_pay_period_489356044.png"; + public string total_color => latest_total_variance >= 0 ? "positive" : "negative"; + public string pay_color => latest_pay_variance >= 0 ? "positive" : "negative"; + public string flex_color => latest_flex_variance >= 0 ? "positive" : "negative"; + + public DeptInfo(string deptName, decimal total, decimal pay, decimal flex) + { + name = deptName; + latest_total_variance = total; + latest_pay_variance = pay; + latest_flex_variance = flex; + } +} + +public static IRestResponse SendMessageByTemplateId(string jsonStr) +{ + RestClient client = new RestClient(); + client.BaseUrl = new Uri("https://api.mailgun.net/v3"); + client.Authenticator = + new HttpBasicAuthenticator("api", + "key-12ea6389d906cef290ad8a0557a3a8c4"); + RestRequest request = new RestRequest(); + request.AddParameter("domain", "notifications-dev.stratanetwork.com", ParameterType.UrlSegment); + request.Resource = "{domain}/messages"; + request.AddParameter("from", "Mailgun Sandbox "); + //request.AddParameter("to", "Dhara "); + //request.AddParameter("to", "Nicole "); + request.AddParameter("to", "Thom Lamb "); + request.AddParameter("to", "Kevin Lamb "); + //request.AddParameter("to", "Shruthi Agni "); + //request.AddParameter("to", "Tucker Debolt "); + request.AddParameter("subject", "Hello Thom Lamb"); + //request.AddParameter("template", "daily_pr_snapshot"); + request.AddParameter("template", "kcl_test"); + request.AddParameter("h:X-Mailgun-Variables", jsonStr); + request.Method = Method.POST; + return client.Execute(request); +} \ No newline at end of file diff --git a/q1.linq b/q1.linq new file mode 100644 index 0000000..62edbaa --- /dev/null +++ b/q1.linq @@ -0,0 +1,58 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.Core + Amazon.Lambda.S3Events + Amazon.Lambda.Serialization.Json + Amazon.Lambda.TestUtilities + AWSSDK.Core + AWSSDK.S3 + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + + +class report +{ + public Guid ReportGUID {get;set;} + public string Category {get;set;} + public string Module {get;set;} + public string Name {get;set;} + public string Description {get;set;} + public string Migration {get;set;} + + public report(Guid reportGuid, string module, string name, string description) + { + ReportGUID = reportGuid; + Module = module; + Name = name; + Description = description; + Category = "Report"; + Migration = string.Empty; + } +}; + +void Main() +{ + var result = procMigrateGenerateAdHocMigration(new Guid("697C3E94-26F8-4F15-9F58-87F54541AD19")); + result.Dump(); + var reportQuery = from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + where rr.IsPublished == true + select new report(rr.ReportGUID, f.Name , rr.Name, rr.Description); +// reportQuery.ToList() +// .ForEach(rpt => rpt.Migration = procMigrateGenerateAdHocMigration(rpt.ReportGUID)); + var json = JsonConvert.SerializeObject(reportQuery.ToList().OrderBy(rpt => rpt.Module).ThenBy(rpt => rpt.Name), Newtonsoft.Json.Formatting.Indented); + json.Dump(); + File.WriteAllText(@"C:\Users\tlamb\Documents\Reports.json", json); + +} + diff --git a/q2.linq b/q2.linq new file mode 100644 index 0000000..bfde279 --- /dev/null +++ b/q2.linq @@ -0,0 +1,135 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + System.Threading.Tasks + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + + +// Define other methods and classes here +// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-s3-developer-guide/blob/master/LICENSE-SAMPLECODE.) + + +class UploadFileMPUHighLevelAPITest +{ + private const string bucketName = "stratasphere"; + private const string keyName = "reports-list"; + private const string filePath = @"C:\Users\tlamb\Documents\Reports.json"; + // Specify your bucket region (an example region is shown). + private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USEast1; + private static IAmazonS3 s3Client; + + public static void Main() + { + s3Client = new AmazonS3Client(bucketRegion); + UploadFileAsync().Wait(); + } + + private static async Task UploadFileAsync() + { + try + { + var fileTransferUtility = + new TransferUtility(s3Client); + + // Option 1. Upload a file. The file name is used as the object key name. + await fileTransferUtility.UploadAsync(filePath, bucketName); + Console.WriteLine("Upload 1 completed"); + + // Option 2. Specify object key name explicitly. + await fileTransferUtility.UploadAsync(filePath, bucketName, keyName); + Console.WriteLine("Upload 2 completed"); + + // Option 3. Upload data from a type of System.IO.Stream. + using (var fileToUpload = + new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + await fileTransferUtility.UploadAsync(fileToUpload, + bucketName, keyName); + } + Console.WriteLine("Upload 3 completed"); + + // Option 4. Specify advanced settings. + var fileTransferUtilityRequest = new TransferUtilityUploadRequest + { + BucketName = bucketName, + FilePath = filePath, + StorageClass = S3StorageClass.StandardInfrequentAccess, + PartSize = 6291456, // 6 MB. + Key = keyName, + CannedACL = S3CannedACL.PublicRead + }; + fileTransferUtilityRequest.Metadata.Add("param1", "Value1"); + fileTransferUtilityRequest.Metadata.Add("param2", "Value2"); + + await fileTransferUtility.UploadAsync(fileTransferUtilityRequest); + Console.WriteLine("Upload 4 completed"); + } + catch (AmazonS3Exception e) + { + Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); + } + catch (Exception e) + { + Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); + } + + } +} diff --git a/q3.linq b/q3.linq new file mode 100644 index 0000000..6ef009b --- /dev/null +++ b/q3.linq @@ -0,0 +1,20 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + + +((SqlConnection)Connection).InfoMessage += (sender, args) => args.Message.Dump(); + +procMigrateGenerateAdHocMigration (new Guid("697C3E94-26F8-4F15-9F58-87F54541AD19")); + diff --git a/q4.linq b/q4.linq new file mode 100644 index 0000000..c2c4bb1 --- /dev/null +++ b/q4.linq @@ -0,0 +1,303 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +private string accessKeyID = "AKIAIZZXT7LVCPR5COFA"; +private string secretKey = "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"; + +void Main() +{ + var process = 3; + var version = (from s in DBSettings where s.Name == "GENERAL_APPVERSION" select s.Setting).SingleOrDefault(); + switch (process) + { + case 1: + var reports = (from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + join up in UserProfiles on rr.AuthorUserGUID equals up.UserGUID into ups + from up in ups.DefaultIfEmpty() + where rr.IsPublished == true + orderby f.Name, rr.Name + select new reportBase(rr.ReportGUID, f.Name, rr.Name, rr.Description, up == null ? rr.AuthorFullName : up.UserName, rr.DateCreated, version)) + .ToList(); + PushReportsJson(reports); + break; + case 2: + PullReportsJson(); + break; + case 3: + JsonConvert.SerializeObject(from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + join up in UserProfiles on rr.AuthorUserGUID equals up.UserGUID into ups + from up in ups.DefaultIfEmpty() + where rr.IsPublished == true + orderby f.Name, rr.Name + select new reportBase(rr.ReportGUID, f.Name, rr.Name, rr.Description, up == null ? rr.AuthorFullName : up.UserName, rr.DateCreated, version), Newtonsoft.Json.Formatting.Indented) + .Dump(); + break; + case 4: + var test = (JArray)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + join up in UserProfiles on rr.AuthorUserGUID equals up.UserGUID into ups + from up in ups.DefaultIfEmpty() + where rr.IsPublished == true + orderby f.Name, rr.Name + select new reportBase(rr.ReportGUID, f.Name, rr.Name, rr.Description, up == null ? rr.AuthorFullName : up.UserName, rr.DateCreated, version), Newtonsoft.Json.Formatting.Indented)); + var modules = (from t in test select (string)t["Module"]).Distinct().ToList(); + modules.Dump(); +// var result = ((JArray)test["Module"]).Distinct().ToList(); +// result.Dump(); + test.Dump(); + break; + default: + var migrations = (from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + join up in UserProfiles on rr.AuthorUserGUID equals up.UserGUID into ups + from up in ups.DefaultIfEmpty() + where rr.IsPublished == true + orderby f.Name, rr.Name + select new report(rr.ReportGUID, f.Name, rr.Name, rr.Description, up == null ? rr.AuthorFullName : up.UserName, rr.DateCreated, version)) + .ToList(); + migrations.ForEach(r => + { + var migration = new StringBuilder(); + ((SqlConnection)Connection).InfoMessage += (sender, args) => migration.AppendLine(args.Message); + procMigrateGenerateAdHocMigration(r.ReportGUID); + r.Migration = migration.ToString(); + }); + UploadReports(migrations); + DumpReports(); + break; + } +} + +void PullReportsJson() +{ + var credentials = new BasicAWSCredentials(accessKeyID, secretKey); + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + var getRequest = new GetObjectRequest + { + BucketName = "stratasphere", + Key = "Reports.json" + }; + var response = client.GetObject(getRequest); + var reader = new StreamReader(response.ResponseStream); + //reader.ReadToEnd().Dump(); + //reader = new StreamReader(response.ResponseStream); + var reports = JsonConvert.DeserializeObject>(reader.ReadToEnd()); + reports.Select(r => new reportBase(r)).Dump(); + } +} + +void PushReportsJson(List reports) +{ + var credentials = new BasicAWSCredentials(accessKeyID, secretKey); + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + var putRequest = new PutObjectRequest + { + BucketName = "stratasphere", + Key = "Reports.json", + ContentType = "text/plain", + ContentBody = JsonConvert.SerializeObject(reports, Newtonsoft.Json.Formatting.None) + }; + client.PutObject(putRequest); + } +} + +void DeleteReports(List reportQuery) +{ + var credentials = new BasicAWSCredentials(accessKeyID, secretKey); + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + reportQuery.Select(q => q.Category).Distinct().ToList() + .ForEach(r => + { + var request = new DeleteObjectRequest + { + BucketName = "stratasphere", + Key = r, + }; + try + { + client.DeleteObject(request); + } + catch (Exception e) + { + e.Dump(); + } + }); + } +} + +void UploadReports(List reportQuery) +{ + $"reports: {reportQuery.Count()}".Dump(); + var credentials = new BasicAWSCredentials(accessKeyID, secretKey); + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + var response = client.ListBuckets(); + response.Buckets.ForEach(b => $"{b.BucketName} {b.CreationDate}".Dump()); + } + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + reportQuery.ToList().ForEach(r => + { + var putRequest = new PutObjectRequest + { + BucketName = "stratasphere", + Key = $"{r.Category}/{r.Module}/{r.ReportGUID}", + ContentType = "text/plain", + ContentBody = JsonConvert.SerializeObject(r, Newtonsoft.Json.Formatting.Indented) + }; + client.PutObject(putRequest); + }); + } + +} + +void DumpReports() +{ + var credentials = new BasicAWSCredentials(accessKeyID, secretKey); + using (var client = new AmazonS3Client(credentials, RegionEndpoint.USEast1)) + { + var request = new Amazon.S3.Model.ListObjectsRequest + { + BucketName = "stratasphere" + }; + + do + { + var response = client.ListObjects(request); + response.Dump(); + + response.S3Objects.Dump(); + response.S3Objects.Where(obj => obj.Key == "Reports.json").Dump(); + + if (response.IsTruncated) + { + request.Marker = response.NextMarker; + } + else + { + request = null; + } + } while (request != null); + } +} + +class reportBase +{ + public Guid ReportGUID { get; set; } + public string Category { get; set; } + public string Module { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string UserName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime UploadDate { get; set; } + public string DbVersion { get; set; } + + public reportBase(Guid reportGuid, string module, string name, string description, string userName, DateTime createdDate, string dbVersion) + { + ReportGUID = reportGuid; + Module = module; + Name = name; + Description = description; + Category = "Report"; + UserName = userName; + CreatedDate = createdDate; + UploadDate = DateTime.Now; + DbVersion = dbVersion; + } + + public reportBase(report r) + { + ReportGUID = r.ReportGUID; + Module = r.Module; + Name = r.Name; + Description = r.Description; + Category = r.Category; + UserName = r.UserName; + CreatedDate = r.CreatedDate; + UploadDate = r.UploadDate; + DbVersion = r.DbVersion; + } +} + +class report : reportBase +{ + public string Migration { get; set; } + + public report(Guid reportGuid, string module, string name, string description, string userName, DateTime createdDate, string dbVersion) + : base(reportGuid, module, name, description, userName, createdDate, dbVersion) + { + Migration = string.Empty; + } + +}; \ No newline at end of file diff --git a/q5.linq b/q5.linq new file mode 100644 index 0000000..57110bc --- /dev/null +++ b/q5.linq @@ -0,0 +1,120 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-01.sdt.local + jazz dev master + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.ComponentModel.Composition + System.ComponentModel.Composition.Hosting + System.ComponentModel.Composition.Primitives + System.ComponentModel.Composition.ReflectionModel + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + System.Net.Http + System.Net.Http.Headers + System.Numerics + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var version = (from s in DBSettings where s.Name == "GENERAL_APPVERSION" select s.Setting).SingleOrDefault(); + + var reportQuery = (from rr in REReports + join f in Folders on rr.FolderGUID equals f.FolderGuid + join up in UserProfiles on rr.AuthorUserGUID equals up.UserGUID into ups + from up in ups.DefaultIfEmpty() + where rr.IsPublished == true + orderby f.Name, rr.Name + select new report(rr.ReportGUID, f.Name, rr.Name, rr.Description, up == null ? rr.AuthorFullName : up.UserName, rr.DateCreated, version)) + .ToList(); + + reportQuery.ForEach(r => + { + var migration = new StringBuilder(); + ((SqlConnection)Connection).InfoMessage += (sender, args) => migration.AppendLine(args.Message); + procMigrateGenerateAdHocMigration(r.ReportGUID); + r.Migration = migration.ToString(); + }); + + reportQuery.Dump(); +} + +// Define other methods and classes here +class report +{ + public Guid ReportGUID { get; set; } + public string Category { get; set; } + public string Module { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string UserName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime UploadDate { get; set; } + public string DbVersion { get; set; } + public string Migration { get; set; } + + public report(Guid reportGuid, string module, string name, string description, string userName, DateTime createdDate, string dbVersion) + { + ReportGUID = reportGuid; + Module = module; + Name = name; + Description = description; + Category = "Report"; + UserName = userName; + CreatedDate = createdDate; + UploadDate = DateTime.Now; + DbVersion = dbVersion; + Migration = string.Empty; + } +}; \ No newline at end of file diff --git a/q6.linq b/q6.linq new file mode 100644 index 0000000..e1572b0 --- /dev/null +++ b/q6.linq @@ -0,0 +1,89 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var storeData = File.ReadAllText(@"D:\patientData.json"); + var chartDto = JArray.Parse(storeData).ToObject>(); + chartDto.Select(d => d.HourOfDay).Where(d => d != null).Dump(); + chartDto.Dump(); +} + +// Define other methods and classes here +public class WasteChartDto +{ + public string HoursOfDay { get; set; } + public string HourOfDay { get; set; } + public string DayOfDay { get; set; } + public string DaysOfWeek { get; set; } + + public double Patient25thVolume { get; set; } + public double PatientMedianVolume { get; set; } + public double Patient75thVolume { get; set; } + public double Patient90thVolume { get; set; } + public double Staff25thVolume { get; set; } + public double StaffMedianVolume { get; set; } + public double Staff75thVolume { get; set; } + public double Staff90thVolume { get; set; } + public double OptimalMedianVolume { get; set; } + public double Acuity25thVolume { get; set; } + public double AcuityMedianVolume { get; set; } + public double Acuity75thVolume { get; set; } + + public WasteChartDto() + { + + } + +} \ No newline at end of file diff --git a/q7.linq b/q7.linq new file mode 100644 index 0000000..85e2828 --- /dev/null +++ b/q7.linq @@ -0,0 +1,89 @@ + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + + +void Main() +{ + var storeData = File.ReadAllText(@"D:\patientDataCNE.json"); + var chartDto = JArray.Parse(storeData).ToObject>(); + chartDto.Select(d => d.HourOfDay).Where(d => d != null).Dump(); + chartDto.Dump(); +} + +// Define other methods and classes here +public class WasteChartDto +{ + public string HoursOfDay { get; set; } + public string HourOfDay { get; set; } + public string DayOfDay { get; set; } + public string DaysOfWeek { get; set; } + + public double Patient25thVolume { get; set; } + public double PatientMedianVolume { get; set; } + public double Patient75thVolume { get; set; } + public double Patient90thVolume { get; set; } + public double Staff25thVolume { get; set; } + public double StaffMedianVolume { get; set; } + public double Staff75thVolume { get; set; } + public double Staff90thVolume { get; set; } + public double OptimalMedianVolume { get; set; } + public double Acuity25thVolume { get; set; } + public double AcuityMedianVolume { get; set; } + public double Acuity75thVolume { get; set; } + + public WasteChartDto() + { + + } + +} \ No newline at end of file diff --git a/test.linq b/test.linq new file mode 100644 index 0000000..bea5b9e --- /dev/null +++ b/test.linq @@ -0,0 +1,301 @@ + + + 77b65bea-e766-4e3c-a1ed-c4c2534b6019 + true + D0001-SQL-11.sdt.local + jazz dev master Prod + true + + <ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll + Amazon.Lambda.S3Events + AWSSDK.Core + AWSSDK.S3 + Amazon + Amazon.Auth.AccessControlPolicy + Amazon.Auth.AccessControlPolicy.ActionIdentifiers + Amazon.Internal + Amazon.Lambda.S3Events + Amazon.MissingTypes + Amazon.Runtime + Amazon.Runtime.CredentialManagement + Amazon.Runtime.CredentialManagement.Internal + Amazon.Runtime.EventStreams + Amazon.Runtime.EventStreams.Internal + Amazon.Runtime.Internal + Amazon.Runtime.Internal.Auth + Amazon.Runtime.Internal.Settings + Amazon.Runtime.Internal.Transform + Amazon.Runtime.Internal.Util + Amazon.Runtime.SharedInterfaces + Amazon.Runtime.SharedInterfaces.Internal + Amazon.S3 + Amazon.S3.Encryption + Amazon.S3.Encryption.Internal + Amazon.S3.Internal + Amazon.S3.IO + Amazon.S3.Model + Amazon.S3.Model.Internal.MarshallTransformations + Amazon.S3.Transfer + Amazon.S3.Util + Amazon.Util + Amazon.Util.Internal + Amazon.Util.Internal.PlatformServices + Newtonsoft.Json + Newtonsoft.Json.Converters + Newtonsoft.Json.Linq + Newtonsoft.Json.Schema + Newtonsoft.Json.Serialization + System + System.Diagnostics + System.Diagnostics.Tracing + System.IO.Compression + ThirdParty.BouncyCastle.Asn1 + ThirdParty.BouncyCastle.Asn1.Utilities + ThirdParty.BouncyCastle.Math + ThirdParty.BouncyCastle.OpenSsl + ThirdParty.BouncyCastle.Utilities.IO.Pem + ThirdParty.Ionic.Zlib + ThirdParty.Json.LitJson + ThirdParty.MD5 + System.ComponentModel + + +private static string tableQuery = @"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE +, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey +FROM INFORMATION_SCHEMA.COLUMNS AS c +LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME +LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME +WHERE c.TABLE_SCHEMA in ('cci', 'dss') +AND (CASE c.TABLE_SCHEMA +WHEN 'cci' THEN 1 +ELSE + CASE WHEN c.TABLE_NAME IN ('DimCaseType', 'CaseTypeFamily', 'CaseTypeFamilyMapping', 'CaseTypeFamilyMappingAPRDRG', 'CaseTypeFamilyMappingICD10', 'CaseTypeFamilyMappingCPT', 'CaseTypeFamilyVersion') + THEN 1 ELSE 0 END END = 1) +AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp') +AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1) +AND tc.CONSTRAINT_TYPE = 'Primary Key' +ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION"; + +private List OrderByStatements; +private List ColumnsToBeExcluded; + +void Main() +{ + OrderByStatements = new List + { + new OrderByInformation("cci.InitiativeWorkflowHistory", new [] {"FromStep","ToStep"}), + new OrderByInformation("cci.VariationEncounterSavingInfo", new []{"EncounterRecordNumber","PhysicianID"}), + new OrderByInformation("cci.FactOpportunityMetric", new []{"FiscalYearID","FiscalMonthID"}), + new OrderByInformation("cci.FactOpportunitySavings", new []{"FiscalyYearID","FiscalMonthID"}), + new OrderByInformation("dss.DimCaseType", new []{"Name"}) + }; + ColumnsToBeExcluded = new List + { + new ColumnsToExclude("cci.SystemSetting", new [] {"IsEncrypted"}), + new ColumnsToExclude("cci.Configuration", new [] {"InitiativeIsSimplifiedWorkflow"}) + }; + + var result = GetTables(); + var tableList = result.Select(r => r.SchemaTable); + var sqlStatements = result.Select(r => r.SqlSelect); + // result.Dump(nameof(result)); + // tableList.Dump(nameof(tableList)); + // sqlStatements.Dump(nameof(sqlStatements)); + var connections = new ServerInstance[] { + new ServerInstance("D0001-SQL-11.sdt.local","jazz dev master Prod", tableList), + new ServerInstance("D0001-SQL-11.sdt.local", "jazz tst master prod", tableList) + }.ToList(); + DoTheComparisons(connections, sqlStatements); +} + +// Define other methods and classes here + +#region Gather Table Information + +public IList
GetTables() +{ + return ExecuteQueryDynamic(tableQuery) + .GroupBy(x => new { x.TABLE_SCHEMA, x.TABLE_NAME }, (g, d) => new Table + { + SchemaName = g.TABLE_SCHEMA, + TableName = g.TABLE_NAME, + Columns = d + .Select(y => new Column + { + ColumnName = y.COLUMN_NAME, + DataType = y.DATA_TYPE, + IsPrimaryKey = y.IsPrimaryKey + }), + OrderBy = OrderByStatements?.SingleOrDefault(obs => obs.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.OrderBy, + Exclude = ColumnsToBeExcluded?.SingleOrDefault(ctbe => ctbe.TableName == $"{g.TABLE_SCHEMA}.{g.TABLE_NAME}")?.ColumnNames ?? new List() + }).ToList(); +} + +public class Table +{ + public string SchemaName { get; set; } + public string TableName { get; set; } + public IEnumerable Columns { get; set; } + public IEnumerable OrderBy { get; set; } + public IEnumerable Exclude { get; set; } + internal string SchemaTable => $"{SchemaName}.{TableName}"; + public string SqlSelect => $"select\r\n\t{SelectColumns}\r\nfrom {SchemaTable} OBJ{OrderByStatement}"; + internal string SelectColumns => !Columns?.Any() ?? true ? "*" : string.Join(",\r\n\t", Columns.Where(c => !Exclude.ToList().Contains(c.ColumnName)).Select(c => c.ColumnName)); + internal string OrderByStatement => !OrderBy?.Any() ?? true ? "" : "\r\nOrder By " + string.Join(", ", OrderBy.Select(ob => $"{ob.ColumnName}{(ob.IsDescending ? " DESC" : "")}")); +} + +public class Column +{ + public string ColumnName { get; set; } + public string DataType { get; set; } + public bool IsPrimaryKey { get; set; } +} + +public class OrderBy +{ + public string ColumnName { get; set; } + public bool IsDescending { get; set; } = false; +} + +public class OrderByInformation +{ + public string TableName { get; set; } + public IEnumerable OrderBy { get; set; } + public OrderByInformation(string tableName, IEnumerable columns) + { + TableName = tableName; + OrderBy = columns.Select(c => new OrderBy + { + ColumnName = c.StartsWith("D|") ? c.Substring(2) : c, + IsDescending = c.StartsWith("D|") + }); + } +} + +public class ColumnsToExclude +{ + public string TableName { get; set; } + public IEnumerable ColumnNames { get; set; } + public ColumnsToExclude(string tableName, IEnumerable columns) + { + TableName = tableName; + ColumnNames = columns; + } +} + +#endregion + +#region Do the comparisons + +public void DoTheComparisons(IEnumerable connections, IEnumerable sqlSelects) +{ + + var sql = string.Join("\r\n", sqlSelects); + var dataLegacy = GetData(connections.First(), sql); + var dataUpdate = GetData(connections.Last(), sql); + + foreach (var dt in Enumerable.Range(0, dataLegacy.Tables.Count)) + { + var legacy = dataLegacy.Tables[dt].Rows; + var update = dataUpdate.Tables[dt].Rows; + var idxCount = legacy.Count; + var compare = new List(); + foreach (var row in Enumerable.Range(0, idxCount)) + { + var r = legacy[row]; + if (row < update.Count) + { + var u = update[row]; + var rJson = JsonConvert.SerializeObject(r.ItemArray); + var uJson = JsonConvert.SerializeObject(u.ItemArray); + if (rJson != uJson) + { + compare.Add(new CompareSet(r, u)); + } + } + else + { + compare.Add(new CompareSet(r, null)); + } + } + if (compare.Any()) + { + compare.Dump(dataLegacy.Tables[dt].TableName, 3); + } + else + { + "No differences found in data".Dump(dataLegacy.Tables[dt].TableName); + } + } +} + +public class ServerInstance +{ + public string Server { get; set; } + public string Database { get; set; } + public IEnumerable TableNames { get; set; } + public ServerInstance(string server, string database, IEnumerable tableNames) + { + Server = server; + Database = database; + TableNames = tableNames; + } +} + +public DataSet GetData(ServerInstance serverInstance, string sql) +{ + var server = serverInstance.Server; + var database = serverInstance.Database; + var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;"; + using (var conn = new SqlConnection(connStr)) + { + var dataset = new DataSet(); + var adapter = new SqlDataAdapter(sql, conn); + adapter.Fill(dataset); + var tableNames = serverInstance.TableNames; + var idx = 0; + foreach (var tableName in tableNames) + { + dataset.Tables[idx].TableName = tableName; + idx += 1; + } + return dataset; + } +} + +public class CompareSet +{ + internal IList ColumnNames {get;set;} + internal IList Legacy { get; set; } + internal IList Update { get; set; } + public IList Rows {get;set;} + public CompareSet(DataRow right, DataRow left) + { + ColumnNames = right.Table.Columns.Cast().Select(dc => dc.ColumnName).ToList(); + Legacy = right.ItemArray.ToList(); + Update = left?.ItemArray.ToList(); + Rows = ColumnNames.Select((c, i) => new Row(c, Legacy[i], Update?[i])).ToList(); + } + +} + +public class Row +{ + public string Column; + public object Left; + public object Right; + public Row(string column, object left, object right) + { + Column = column; + Left = left; + Right = right; + } + + object ToDump() => new{ + Column = Left.Equals(Right ?? "") ? (object)Column : new XElement("LINQPad.HTML", new XElement("div", new XAttribute("style", "background-color:lightyellow;color:black"), Column)), + Left, + Right, + }; +} + +#endregion diff --git a/webex.exe b/webex.exe new file mode 100644 index 0000000..6bbc3b7 Binary files /dev/null and b/webex.exe differ