├── sc-list.txt
├── .DS_Store
├── docker-compose.yml
├── module.xml
├── irissession.sh
├── Dockerfile
├── LICENSE
├── Installer.cls
├── README.md
└── src
└── cls
└── IDP
└── DV.cls
/sc-list.txt:
--------------------------------------------------------------------------------
1 | CDV.pkg
2 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/intersystems-community/CDV/master/.DS_Store
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 | services:
3 | iris:
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | restart: always
8 | ports:
9 | - 1972
10 | - 51773
11 | - 52773
12 | - 53773
13 | volumes:
14 | - ~/iris.key:/usr/irissys/mgr/iris.key
15 | - ./:/irisdev/app
16 |
--------------------------------------------------------------------------------
/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | idp-dv
6 | 1.3.1
7 | Class data verifier. Utility validates Intersystems IRIS classes properties data according to the properties' types.
8 | module
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/irissession.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | iris start $ISC_PACKAGE_INSTANCENAME quietly
4 |
5 | cat << EOF | iris session $ISC_PACKAGE_INSTANCENAME -U %SYS
6 | do ##class(%SYSTEM.Process).CurrentDirectory("$PWD")
7 | $@
8 | if '\$Get(sc) do ##class(%SYSTEM.Process).Terminate(, 1)
9 | zn "%SYS"
10 | do ##class(SYS.Container).QuiesceForBundling()
11 | Do ##class(Security.Users).UnExpireUserPasswords("*")
12 | halt
13 | EOF
14 |
15 | exit=$?
16 |
17 | iris stop $ISC_PACKAGE_INSTANCENAME quietly
18 |
19 | exit $exit
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG IMAGE=store/intersystems/irishealth:2019.3.0.308.0-community
2 | ARG IMAGE=store/intersystems/iris-community:2019.3.0.309.0
3 | ARG IMAGE=store/intersystems/iris-community:2019.4.0.379.0
4 | ARG IMAGE=store/intersystems/iris-community:2020.1.0.199.0
5 | # ARG IMAGE=intersystemsdc/iris-community:2019.4.0.383.0-zpm
6 | ARG IMAGE=intersystemsdc/iris-community:2020.4.0.524.0-zpm
7 | ARG IMAGE=intersystemsdc/iris-community:latest
8 | FROM $IMAGE
9 |
10 | USER root
11 |
12 | WORKDIR /opt/irisapp
13 | RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp
14 |
15 | USER irisowner
16 |
17 | COPY Installer.cls .
18 | COPY src src
19 | COPY irissession.sh /
20 | SHELL ["/irissession.sh"]
21 |
22 | RUN \
23 | do $SYSTEM.OBJ.Load("Installer.cls", "ck") \
24 | set sc = ##class(App.Installer).setup()
25 |
26 | # bringing the standard shell back
27 | SHELL ["/bin/bash", "-c"]
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 InterSystems Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Installer.cls:
--------------------------------------------------------------------------------
1 | Class App.Installer
2 | {
3 |
4 | XData setup
5 | {
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
24 | }
25 |
26 | ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]
27 | {
28 | #; Let XGL document generate code for this method.
29 | Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "setup")
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IDP DV
2 |
3 | ## Instalation
4 |
5 | To install IDP.DV, you just need to dowload and import the package [IDP.DV](https://github.com/intersystems-ru/CDV/releases) file.
6 | Some ways to import IDP package:
7 | - Go to Management Portal -> System Explorer -> Classes -> Import and select the XML file.
8 | - Drag the file over Studio
9 | - Terminal command:
10 |
11 | ```
12 | Do $system.OBJ.Load("yourpath/IDP.DV.xml","ck")
13 | ```
14 |
15 | ## Docker
16 |
17 | To install using Docker. Follow this instructions:
18 |
19 | Open terminal and clone the repo into any local directory
20 |
21 | ```
22 | $ git clone https://github.com/intersystems-ru/CDV.git
23 | ```
24 |
25 | Open the terminal in this directory and run:
26 |
27 | ```
28 | $ docker-compose build
29 | ```
30 |
31 | Run the IRIS container with your project:
32 | ```
33 | $ docker-compose up -d
34 | ```
35 |
36 | ### How to Run the Application
37 | Open InterSystems IRIS terminal:
38 |
39 | ```
40 | $ docker-compose exec iris iris session iris
41 | USER>zn "IRISAPP"
42 | IRISAPP>set st = ##class(IDP.DV).ScanAllClasses(.Oid)
43 | IRISAPP>zw Oid
44 | ```
45 |
46 | ## Usage
47 |
48 | s st = ##class(IDP.DV).ScanAllClasses(.Oid) - for all user classes
49 | s st = ##class(IDP.DV).ScanSubclassesOf(Class, .Oid) - for subclasses
50 | s st = ##class(IDP.DV).ScanMatchingClasses(Mask, .Oid) - for LIKE SQL
51 |
52 | The utility works only in a current namespace.
53 |
54 | Arguments:
55 |
56 | - `Oid` - Output structure, that stores data about invalid objects in a classes
57 | - `Class` - Scan all subclasses Of a class (and class itself).
58 | - `Mask` - Passed into the SQL query `SELECT ID FROM %Dictionary.ClassDefinition Where ID LIKE ?`
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/src/cls/IDP/DV.cls:
--------------------------------------------------------------------------------
1 | Class IDP.DV
2 | {
3 |
4 | ClassMethod ScanAllClasses(ByRef Oid As %String) As %Status
5 | {
6 | #Dim sc As %Status = $$$OK
7 | set sc = $System.OBJ.GetClassList(.Classes, "/application=0 /system=0 /percent=0 /mapped=0")
8 | Quit:$$$ISERR(sc)
9 | Set sc = ..ScanClassLocal(.Classes, .Oid)
10 | Quit sc
11 | }
12 |
13 | ClassMethod ScanSubclassesOf(Class As %String, ByRef Oid As %String) As %Status
14 | {
15 | #Dim sc As %Status = $$$OK
16 | Set RS = ##class(%ResultSet).%New("%Dictionary.ClassDefinition:SubclassOf")
17 | Set sc = RS.%Execute(Class)
18 | Quit:$$$ISERR(sc)
19 |
20 | Set Classes(Class) = ""
21 |
22 | While (RS.%Next(.sc)) {
23 | Quit:$$$ISERR(sc)
24 | Set Classes(RS.Data("Name")) = ""
25 | }
26 |
27 | Set sc = ..ScanClassLocal(.Classes, .Oid)
28 | Quit sc
29 | }
30 |
31 | ClassMethod ScanMatchingClasses(Mask As %String, ByRef Oid As %String) As %Status
32 | {
33 | #Dim sc As %Status = $$$OK
34 |
35 | Set SQL = "SELECT ID FROM %Dictionary.ClassDefinition Where ID LIKE ?"
36 | Set ST = ##class(%SQL.Statement).%New()
37 | Set sc = ST.%Prepare(SQL)
38 | Quit:$$$ISERR(sc) sc
39 |
40 | #Dim RS As %SQL.StatementResult
41 | Set RS = ST.%Execute(Mask)
42 |
43 | While RS.%Next() {
44 | Set Classes(RS.%GetData(1)) = ""
45 | }
46 |
47 | Set sc = ..ScanClassLocal(.Classes, .Oid)
48 | Quit sc
49 | }
50 |
51 | ClassMethod ScanClassLocal(ByRef Classes As %String, ByRef Oid As %String) As %Status
52 | {
53 | #Dim sc,sc1 As %Status = $$$OK
54 | Set Class = ""
55 | For {
56 | Set Class = $Order(Classes(Class))
57 | Quit:Class=""
58 | If (##class(%Dictionary.CompiledClass).%ExistsId(Class) && $classmethod(Class, "%Extends", "%Library.Persistent"))
59 | {
60 | Set sc1 = ..ValidateClassObjects(Class, .Oid)
61 | }
62 | Set sc = $$$ADDSC(sc, sc1)
63 | }
64 |
65 | Quit sc
66 | }
67 |
68 | ClassMethod ValidateClassObjects(Class As %String, ByRef Oid As %String) As %Status
69 | {
70 | #Dim sc As %Status = $$$OK
71 |
72 | w !,"__________________________________________________________________________________",!
73 | set Oid(Class) = 0
74 | set query = ##class(%SQL.Statement).%New()
75 | set sc = query.%PrepareClassQuery(Class,"Extent")
76 | return:$$$ISERR(sc) sc
77 | set rset=query.%Execute()
78 |
79 | While (rset.%Next())
80 | {
81 | set obj = $classmethod(Class, "%OpenId", rset.%Get("ID"))
82 | do $system.CLS.SetModified(obj, 1)
83 |
84 | set sc = obj.%ValidateObject()
85 | if $$$ISERR(sc)
86 | {
87 | w !,"Class: ",Class,!,"Object: ", rset.%Get("ID"),!
88 | w "-----------------------------------------------"
89 | do $system.Status.DisplayError(sc)
90 | w !,!,!
91 | set Oid(Class) = Oid(Class) + 1
92 | set Oid(Class, rset.%Get("ID")) = sc
93 | }
94 | Kill obj, valid
95 | }
96 | w !,Class, " has ",Oid(Class)," invalid objects "
97 | set Oid(Class) = "has "_Oid(Class)_" invalid objects"
98 | Quit sc
99 | }
100 |
101 | }
102 |
103 |
--------------------------------------------------------------------------------