Changing RowIds when saving cache object that uses cache sql storage - intersystems-cache

First I apologise for the lengh of this question..
I have a global set up in the following manner:
^WHEAIPP(1,116444,1)=3
^WHEAIPP(1,116444,1,1)="58898^^LSWELFER^58898,0"
^WHEAIPP(1,116444,1,2)="58898^59128^MPHILLIPS^59135,0"
^WHEAIPP(1,116444,1,3)="62626^62745^FXALTMAN^62626,58427^^^^^^2^"
^WHEAIPP(1,116444,2)=3
^WHEAIPP(1,116444,2,1)="59129^^MPHILLIPS^59910,0^^^^^^"
^WHEAIPP(1,116444,2,2)="59129^59547^SSNARE^59934,0^^^^^^"
^WHEAIPP(1,116444,2,3)="59129^62954^FXALTMAN^62654,32289^^^^^^3^"
^WHEAIPP(1,116444,3)=4
^WHEAIPP(1,116444,3,1)="60311^^SALFANO^60311,0^^^^^^"
^WHEAIPP(1,116444,3,2)="60311^^SSNARE^60754,0^^^^^^2"
^WHEAIPP(1,116444,3,3)="60311^^NEPAXSON^60757,0^^^^^^2"
^WHEAIPP(1,116444,3,4)="60311^62636^FXALTMAN^62626,58428^=^100^=^25^^5"
^WHEAIPP(1,116444,4)=4
^WHEAIPP(1,116444,4,1)="59548^^SSNARE^59550,0"
^WHEAIPP(1,116444,4,2)="59548^60310^SSNARE^59934,0^^^^^^2"
^WHEAIPP(1,116444,4,3)="62626^^FXALTMAN^62626,61050^^^^^^^1"
^WHEAIPP(1,116444,4,4)="62617^62647^FXALTMAN^62627,27518^^^^^^4"
The first subscript is an internal Hmo, the sceond is an internal provide, the third is a line number and the last is a line detail number. The data at the 4th subscript level is a combined audit trail history of the line with the highest line detail number being the current line.
I have 3 classes set-up with parent child relationships as follows:
The main class
Class XFXA.Try3.IppProv Extends (%Persistent, %Populate, %XML.Adaptor) [ ClassType =
persistent, Inheritance = right, ProcedureBlock, SqlRowIdName = Id, StorageStrategy
= SQLMapping ]
{
Property Hmo As %Integer [ Required ];
Property Keen As %Integer [ Required ];
/// Contains the array of data initially loaded into the class
Property OriginalData As %String [ MultiDimensional ];
Property ReadyToFile As %Boolean [ InitialExpression = 0, Transient ];
Relationship IppLines As XFXA.Try3.IppProvLine [ Cardinality = children, Inverse =
relIppProv ];
Index iMaster On (Hmo, Keen) [ IdKey, PrimaryKey, Unique ];
.
.
.
<Storage name="SQLMapping">
<DataLocation>^[%extRef("UCKE"),%extRef("SYKE")]WHEAIPP</DataLocation>
<ExtentSize>100000</ExtentSize>
<SequenceNumber>19</SequenceNumber>
<SQLMap name="DBMS">
<Global>^[%extRef("UCKE"), %extRef("SYKE")]WHEAIPP</Global>
<Structure>delimited</Structure>
<Subscript name="1">
<Expression>{Hmo}</Expression>
</Subscript>
<Subscript name="2">
<Expression>{Keen}</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^XFXA.Try3.IppProvS</StreamLocation>
<Type>%Library.CacheSQLStorage</Type>
</Storage>
}
The Line class
Class XFXA.Try3.IppProvLine Extends (%Persistent, %Populate, %XML.Adaptor) [ ClassType
= persistent, Inheritance = right, ProcedureBlock, SqlRowIdName = Id, StorageStrategy
=SQLMapping ]
{
Relationship relIppProv As XFXA.Try3.IppProv [ Cardinality = parent, Inverse =
IppLines ];
Relationship IppLineDetail As XFXA.Try3.IppProvLineDetail [ Cardinality = children,
Inverse = relIppProvLinex ];
Property Line As %String;
Property IppLineDetailCount As %String;
Index iMaster On Line [ IdKey, PrimaryKey, Unique ];
.
.
.
<Storage name="SQLMapping">
<ExtentSize>100000</ExtentSize>
<SequenceNumber>14</SequenceNumber>
<SQLMap name="DBMS">
<Data name="IppLineDetailCount">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>1</Piece>
</Data>
<Global>^[%extRef("UCKE"), %extRef("SYKE")]WHEAIPP</Global>
<Structure>delimited</Structure>
<Subscript name="1">
<Expression>{XFXA_Try3.IppProv.Hmo}</Expression>
</Subscript>
<Subscript name="2">
<Expression>{XFXA_Try3.IppProv.Keen}</Expression>
</Subscript>
<Subscript name="3">
<Expression>{Line}</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^XFXA.Try3.IppProvLineS</StreamLocation>
<Type>%Library.CacheSQLStorage</Type>
</Storage>
}
The Line Detail Class
Class XFXA.Try3.IppProvLineDetail Extends (%Persistent, %XML.Adaptor) [ ClassType =
persistent, Inheritance = right, ProcedureBlock, SqlRowIdName = Id, StorageStrategy =
SQLMapping ]
{
Relationship relIppProvLinex As XFXA.Try3.IppProvLine [ Cardinality = parent, Inverse =
IppLineDetail ];
Property LnDetail As %String;
Index iMaster On LnDetail [ IdKey, PrimaryKey, Unique ];
.
.
.
<Storage name="SQLMapping">
<ExtentSize>100000</ExtentSize>
<SQLMap name="DBMS">
<Data name="ClmAmtAllowed">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>6</Piece>
</Data>
<Data name="ClmLineAmtAllowed">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>8</Piece>
</Data>
<Data name="ClmLineOp">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>7</Piece>
</Data>
<Data name="ClmOp">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>5</Piece>
</Data>
<Data name="Deleted">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>11</Piece>
</Data>
<Data name="EffDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>1</Piece>
</Data>
<Data name="IppCode">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>10</Piece>
</Data>
<Data name="LastChgDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>4</Piece>
</Data>
<Data name="PxDxCdeFlag">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>9</Piece>
</Data>
<Data name="TermDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>2</Piece>
</Data>
<Data name="UserIni">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>3</Piece>
</Data>
<Global>^[%extRef("UCKE"), %extRef("SYKE")]WHEAIPP</Global>
<Structure>delimited</Structure>
<Subscript name="1">
<Expression>{XFXA_Try3.IppProv.Hmo}</Expression>
</Subscript>
<Subscript name="2">
<Expression>{XFXA_Try3.IppProv.Keen}</Expression>
</Subscript>
<Subscript name="3">
<Expression>{XFXA_Try3.IppProvLine.Line}</Expression>
</Subscript>
<Subscript name="4">
<Expression>{LnDetail}</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^XFXA.Try3.IppProvLineDetails</StreamLocation>
<Type>%Library.CacheSQLStorage</Type>
</Storage>
}
When the user marks a line for deletion, a deleted flag is set to 1 in the current detail line at the 4th subscript level AND if this line is not the last line, the filing code moves to be the last line. If I try to do this in a delete method from my main class, I get an error message that says Updating RowIds is not allowed. this is because I tried to manipulate the Line property of the line class moving lines around to push the deleted one to the end. A check of the documentation found AllowRowIDUpdate with some warnings but not clear example of how to use it. Does anyone know of a way to accomplish this?

Well, the documentation on AllowRowIDUpdate says
"Set to 1 only if you are doing your own filing in a BEFORE trigger
and using the %SkipFiling flag. Otherwise, use the default of 0".
If you do your own filing in a BEFORE trigger and using the %SkipFiling flag then you mostly aren't using SQL Storage to store the data, you are just exposing your own storage so that it can be used via SQL.
I would suggest that the easiest thing to do would be to not update RowIDs. Instead of using update, use insert and delete to move the lines. This is essentially the same thing you would have to do using straight global access, since you can't update subscripts, per se, either.
Also, it's out of the scope of your question, but do I would consider different storage if I could. Moving line numbers around so there are no gaps doesn't seem to accomplish much when the line numbers are really stored in some kind of BTree like structure anyway, so maybe you could just leave gaps?

It's almost always better to use a synthetic/surrogate key that doesn't need to change.

Related

How in Powershell see all XML Levels

I have a test xml and I want to get the value from this line ATTRIBUTE NAME="News- offers_OPT_EMAIL">F
so I can check for the value F or T
if I do below I can get the title but how do I get the above line value.
[xml]$xml = Get-Content testFile.xml
$xml
$xml.CUSTOMERS.CUSTOMER.NAME.TITLE
sample XML code
<?xml version="1.0" encoding="UTF-8"?>
<CUSTOMERS xml:lang="en">
<CUSTOMER CREATED_DATE="2018-01-01 05:18:53.0" GROUP_ID="" ID="95656565">
<NAME>
<TITLE>M</TITLE>
<FIRST_NAME>Joe</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
</NAME>
<GENDER/>
<DATE_OF_BIRTH/>
<ADDRESS>
<ADDRESS_LINE_1>1 White House</ADDRESS_LINE_1>
<ADDRESS_LINE_2>Old Ave</ADDRESS_LINE_2>
<ADDRESS_LINE_3/>
<TOWNCITY>LONDON</TOWNCITY>
<COUNTY/>
<POSTCODE>18659</POSTCODE>
<COUNTRY>France</COUNTRY>
</ADDRESS>
<ADDRESS>
<ADDRESS_LINE_1>175 avenue de la division Leclerc</ADDRESS_LINE_1>
<ADDRESS_LINE_2/>
<ADDRESS_LINE_3/>
<TOWNCITY>Antony</TOWNCITY>
<COUNTY/>
<POSTCODE>92160</POSTCODE>
<COUNTRY>France</COUNTRY>
</ADDRESS>
<CONTACT_DETAILS>
<TELEPHONE MARKETING_OPT_IN="F" TYPE="MOBILE">0123456789</TELEPHONE>
<EMAIL MARKETING_OPT_IN="F">johnsmith#gmail.com</EMAIL>
</CONTACT_DETAILS>
<ATTRIBUTE NAME="News- offers_OPT_EMAIL">F</ATTRIBUTE>
<NOTE>NA</NOTE>
</CUSTOMER>
You could use SelectSingleNode or SelectNodes with an XPath expression. There are several options to achieve what you want, depending on your intention, but this would be one way to do it:
# finde the nodes
$nodes = $xml.SelectNodes("//*[local-name()='ATTRIBUTE'][#NAME='News- offers_OPT_EMAIL']")
# get value
$nodes.InnerText
Or if the value of the attribute doesn't matter, simply do:
$xml.customers.customer.attribute.'#text'

SWXMLHash can't parse a [XMLIndexer]

I am trying for first time to parse a XML file and I am using SWXMLHash.
My xml file is:
<weatherdata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://api.met.no/weatherapi/locationforecast/1.9/schema" created="2018-02-13T18:12:31Z">
<meta>
<model name="LOCAL" termin="2018-02-13T12:00:00Z" runended="2018-02-13T14:27:32Z" nextrun="2018-02-13T22:00:00Z" from="2018-02-13T19:00:00Z" to="2018-02-16T06:00:00Z" />
<model name="EPS" termin="2018-02-13T00:00:00Z" runended="2018-02-13T09:03:05Z" nextrun="2018-02-13T22:00:00Z" from="2018-02-16T12:00:00Z" to="2018-02-22T18:00:00Z" />
</meta>
<product class="pointData">
<time datatype="forecast" from="2018-02-13T19:00:00Z" to="2018-02-13T19:00:00Z">
<location altitude="0" latitude="" longitude="">
<temperature id="TTT" unit="celsius" value="3.5"/>
<windDirection id="dd" deg="158.8" name="S"/>
<windSpeed id="ff" mps="8.8" beaufort="5" name="Frisk bris"/>
<windGust id="ff_gust" mps="15.0"/>
<areaMaxWindSpeed mps="13.8"/>
<humidity value="82.1" unit="percent"/>
<pressure id="pr" unit="hPa" value="1002.5"/>
<cloudiness id="NN" percent="99.3"/>
<fog id="FOG" percent="0.0"/>
<lowClouds id="LOW" percent="73.2"/>
<mediumClouds id="MEDIUM" percent="0.0"/>
<highClouds id="HIGH" percent="91.0"/>
<dewpointTemperature id="TD" unit="celsius" value="0.6"/>
</location>
</time>
The <time> </time> repeates.
Having made a let parsedResultXML = SWXMLHash.parse(data)
I am trying to parse with a for in loop
for node in parsedResultXML["weatherdata"]["product"]["time"].all{
print(node)
}
I get results
<time to="2018-02-14T01:00:00Z" from="2018-02-14T01:00:00Z" datatype="forecast">
<location latitude="" longitude="" altitude="0">
<temperature id="TTT" unit="celsius" value="3.4"></temperature>
<windDirection id="dd" name="S" deg="158.7"></windDirection>
<windSpeed name="Liten kuling" mps="11.1" id="ff" beaufort="6"></windSpeed>
<windGust id="ff_gust" mps="19.0"></windGust>
<areaMaxWindSpeed mps="17.5"></areaMaxWindSpeed>
<humidity unit="percent" value="88.3"></humidity>
<pressure id="pr" unit="hPa" value="1002.5"></pressure>
<cloudiness id="NN" percent="99.3"></cloudiness>
<fog id="FOG" percent="0.1"></fog>
<lowClouds id="LOW" percent="98.6"></lowClouds>
<mediumClouds id="MEDIUM" percent="93.4"></mediumClouds>
<highClouds id="HIGH" percent="57.8"></highClouds>
<dewpointTemperature id="TD" unit="celsius" value="1.5"></dewpointTemperature>
</location>
</time>
But I can't access the elements.
Using
for node in parsedResultXML["weatherdata"]["product"]["time"].all{
node["time"].element?.attribute(by: "from")?.text
}
I don't get any results back.
Any idea??
Thanks
You're close... as #rmaddy commented, node is already indexed to "time". So instead of:
for node in parsedResultXML["weatherdata"]["product"]["time"].all {
node["time"].element?.attribute(by: "from")?.text
}
Do this instead:
for node in parsedResultXML["weatherdata"]["product"]["time"].all {
node.element?.attribute(by: "from")?.text
}

Intersystems caché - sql storage definition

How to set Name property of %Dictionary.StorageSQLMapDefinition class?
I have this code:
set storMaps = ##class(%Dictionary.StorageSQLMapDefinition).%New()
set storMaps.Name = ?????
And i don´t know how to set storMaps.Name. Data type of Name prop. is %Dictionary.SQLIdentifier according to documentation. But i don´t know how to set this property. I get an error:
SQL Map type is invalid
You maybe forgot about %Dictionary.StorageDefintion.
set clsDef=##class(%Dictionary.ClassDefinition).%OpenId("User.Test")
set storage=##class(%Dictionary.StorageDefinition).%New()
set storage.Name="Test"
set storage.Type="%CacheSQLStorage" // this is important
set storageMap=##class(%Dictionary.StorageSQLMapDefinition).%New()
set storageMap.Name="MasterMap"
set storageMap.Global="^global"
do storage.SQLMaps.Insert(storageMap)
set data=##class(%Dictionary.StorageSQLMapDataDefinition).%New()
set data.Name="name"
set data.Node=1
do storageMap.Data.Insert(data)
set data=##class(%Dictionary.StorageSQLMapDataDefinition).%New()
set data.Name="type"
set data.Node=2
do storageMap.Data.Insert(data)
set subscript=##class(%Dictionary.StorageSQLMapSubDefinition).%New()
set subscript.Name=1
set subscript.Expression="""test"""
do storageMap.Subscripts.Insert(subscript)
set subscript=##class(%Dictionary.StorageSQLMapSubDefinition).%New()
set subscript.Name=2
set subscript.Expression="{ID}"
do storageMap.Subscripts.Insert(subscript)
set rowidspec=##class(%Dictionary.StorageSQLMapRowIdSpecDefinition).%New()
set rowidspec.Name=1
set rowidspec.Expression="{L2}"
set rowidspec.Field="ID"
do storageMap.RowIdSpecs.Insert(rowidspec)
do clsDef.Storages.Insert(storage)
set tSC=clsDef.%Save()
code above will create storage like this
<Storage name="Test">
<SQLMap name="MasterMap">
<Data name="name">
<Node>1</Node>
</Data>
<Data name="type">
<Node>2</Node>
</Data>
<Global>^global</Global>
<RowIdSpec name="1">
<Expression>{L2}</Expression>
<Field>ID</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>"test"</Expression>
</Subscript>
<Subscript name="2">
<Expression>{ID}</Expression>
</Subscript>
</SQLMap>
<Type>%CacheSQLStorage</Type>
</Storage>

Intersystems caché - sqlStorage

I need to map my global to sql. I have global structure like this:
^myGlob("mltab","main","Dta",idRow,idCol,"Index")
concretely:
^myGlob("mltab","main","Dta",3,1) = 20
^myGlob("mltab","main","Dta",3,2) = 30
^myGlob("mltab","main","Dta",3,2,"Index") = "t|1320|30|62913"
^myGlob("mltab","main","Dta",3,3) = "01.04.2013"
^myGlob("mltab","main","Dta",3,4) = 36
^myGlob("mltab","main","Dta",3,5) = 166.8
^myGlob("mltab","main","Dta",4,1) = 20
^myGlob("mltab","main","Dta",4,2) = 30
^myGlob("mltab","main","Dta",4,3) = "01.04.2013"
^myGlob("mltab","main","Dta",4,4) = 36
^myGlob("mltab","main","Dta",4,4,"Index") = "nextIndexVal"
^myGlob("mltab","main","Dta",4,5) = 166.8
.
.
.
"mltab","main","Dta" and "Index" are constant. idRow is my primary key and idCol isn't important for me, but causes me problem, because it can change.
I need to get something like colId=2^index="t|1320|30|62913" value to some table column(map class property). Other values I have mapped.
my current code looks like this:
Class Kza.NewClass1 Extends %Persistent [ Not ProcedureBlock, StorageStrategy = MySqlStorageStrategy ]
{
Property hyperlink As %String;
Property colId As %String;
Property id As %Integer;
Property prop1 As %String;
Property prop2 As %String;
Property prop3 As %String;
Property prop4 As %String;
Property prop5 As %String;
Index MyIndex1 On id [ IdKey, PrimaryKey, Unique ];
<Storage name="MySqlStorageStrategy">
<ExtentSize>100000</ExtentSize>
<SQLMap name="Map1">
<Global>^myGlob</Global>
<RowIdSpec name="1">
<Expression>{L2}</Expression>
<Field>id</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>{id}</Expression>
</Subscript>
<Subscript name="2">
<Expression>{colId}</Expression>
</Subscript>
<Type>index</Type>
</SQLMap>
<SQLMap name="MyMasterMap">
<ConditionalWithHostVars></ConditionalWithHostVars>
<Data name="colId">
<Node>6</Node>
</Data>
<Data name="hyperlink">
<Node>"Index"</Node>
</Data>
<Data name="prop1">
<Node>1</Node>
</Data>
<Data name="prop2">
<Node>2</Node>
</Data>
<Data name="prop3">
<Node>3</Node>
</Data>
<Data name="prop4">
<Node>4</Node>
</Data>
<Data name="prop5">
<Node>5</Node>
</Data>
<Global>^myGlob</Global>
<RowIdSpec name="1">
<Expression>{L1}</Expression>
<Field>id</Field>
</RowIdSpec>
<Subscript name="1">
<Expression>"mltab"</Expression>
</Subscript>
<Subscript name="2">
<Expression>"main"</Expression>
</Subscript>
<Subscript name="3">
<Expression>"Dta"</Expression>
</Subscript>
<Subscript name="4">
<Expression>{id}</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^Kza.testToTable1S</StreamLocation>
<Type>%CacheSQLStorage</Type>
</Storage>
}
I think my problem may be in data node definition:
<Data name="colId">
<Node>6</Node>
</Data>
<Data name="hyperlink">
<Node>"Index"</Node>
</Data>
but sadly, I am not familiar with this issue enough... So can someone help me to get column hyperlink in my sql table with value colId=2^index=t|1320|30|62913 on row with id 3 and colId=4^index=nextIndexVal on row id 4?
If colId for hyperlink property fixed, you can use tag RetrievalCode where possible to write some COS code, if not fixed, you can write something for retreive colId and then like here
<Data name="hyperlink">
<RetrievalCode> s {hyperlink}=$g(^myGlob("mltab","main","Dta",{L4},2,"Index"))
</RetrievalCode>
</Data>
and your RowIdSpec maybe wrong, because, property id on 4 level of subscripts, so you have use L4 for expression.
<RowIdSpec name="1">
<Expression>{L4}</Expression>
<Field>id</Field>
</RowIdSpec>
and latest variant
<Data name="colId">
<RetrievalCode>s {*}="" f { s {*}=$o(^myGlob({L1},{L2},{L3},{L4},{*})) quit:{*}="" quit:$d(^myGlob({L1},{L2},{L3},{L4},{*},"Index"))}
</RetrievalCode>
</Data>
<Data name="hyperlink">
<RetrievalCode>s colId="" f { s colId=$o(^myGlob({L1},{L2},{L3},{L4},colId)) quit:colId="" quit:$d(^myGlob({L1},{L2},{L3},{L4},colId,"Index"))}
s {*}=$g(^myGlob({L1},{L2},{L3},{L4},colId,"Index"))
</RetrievalCode>
</Data>
<Data name="hyperlink2">
<RetrievalCode>s colId="" f { s colId=$o(^myGlob({L1},{L2},{L3},{L4},colId)) quit:colId="" quit:$d(^myGlob({L1},{L2},{L3},{L4},colId,"Index"))}
s {*}="colId="_colId_"^index="""_$g(^myGlob({L1},{L2},{L3},{L4},colId,"Index"))_""""
</RetrievalCode>
</Data>
This code in SQLMap storage do it:
<Data name="hyperlink">
<RetrievalCode>
<![CDATA[set res=""
set colId=""
for
{
set colId = $order( ^myGlob("mltab","main","Dta",{L4},colId) )
quit:(colId = "")
set indexTab = $g(^myGlob("mltab","main","Dta",{L4},colId,"Index"))
if indexTab'="" {
set res = res_"colId="_colId_"index="_indexTab
}
}
s {hyperlink}=res]]></RetrievalCode>
</Data>
{L4} is row id, and no more than one SQLmap is required

Cache Class compilation error using parent-child relationships and cache sql storage

I have the global listed below that I'm trying to create a couple of cache classes using sql stoarage for:
^WHEAIPP(1,26,1)=2
^WHEAIPP(1,26,1,1)="58074^^SMSNARE^58311"
2)="58074^59128^MPHILLIPS^59135"
^WHEAIPP(1,29,1)=2
^WHEAIPP(1,29,1,1)="58074^^SMSNARE^58311"
2)="58074^59128^MPHILLIPS^59135"
^WHEAIPP(1,93,1)=2
^WHEAIPP(1,93,1,1)="58884^^SSNARE^58948"
2)="58884^59128^MPHILLIPS^59135"
^WHEAIPP(1,166,1)=2
^WHEAIPP(1,166,1,1)="58407^^SMSNARE^58420"
2)="58407^59128^MPHILLIPS^59135"
^WHEAIPP(1,324,1)=2
^WHEAIPP(1,324,1,1)="58884^^SSNARE^58948"
2)="58884^59128^MPHILLIPS^59135"
^WHEAIPP(1,419,1)=3
^WHEAIPP(1,419,1,1)="59707^^SSNARE^59708"
2)="59707^^MPHILLIPS^59910,58000^^^^"
3)="59707^59981^SSNARE^60117,53241^^^^"
The first two subscripts of the global (Hmo and Keen) make a unique entry. The third subscript (Seq) has a property (IppLineCount) which is the number of IppLines in the fourth subscript level (Seq2). I create the class WIppProv below which is the parent class:
/// <PRE>
/// ============================
/// Generated Class Definition
/// Table: WMCA_B_IPP_PROV
/// Generated by: FXALTMAN
/// Generated on: 05/21/2012 13:46:41
/// Generator: XWESTblClsGenV2
/// ----------------------------
/// </PRE>
Class XFXA.MCA.WIppProv Extends (%Persistent, %XML.Adaptor) [ ClassType = persistent, Inheritance = right, ProcedureBlock, StorageStrategy = SQLMapping ]
{
/// .HMO
Property Hmo As %Integer;
/// .KEEN
Property Keen As %Integer;
/// .SEQ
Property Seq As %String;
Property IppLineCount As %Integer;
Index iMaster On (Hmo, Keen, Seq) [ IdKey, Unique ];
Relationship IppLines As XFXA.MCA.WIppProvLine [ Cardinality = many, Inverse = relWIppProv ];
<Storage name="SQLMapping">
<DataLocation>^WHEAIPP</DataLocation>
<ExtentSize>1000000</ExtentSize>
<SQLMap name="DBMS">
<Data name="IppLineCount">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>1</Piece>
</Data>
<Global>^WHEAIPP</Global>
<PopulationType>full</PopulationType>
<Subscript name="1">
<AccessType>Sub</AccessType>
<Expression>{Hmo}</Expression>
<LoopInitValue>1</LoopInitValue>
</Subscript>
<Subscript name="2">
<AccessType>Sub</AccessType>
<Expression>{Keen}</Expression>
</Subscript>
<Subscript name="3">
<AccessType>Sub</AccessType>
<LoopInitValue>1</LoopInitValue>
<Expression>{Seq}</Expression>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^XFXA.MCA.WIppProvS</StreamLocation>
<Type>%Library.CacheSQLStorage</Type>
</Storage>
}
This class compiles fine. Next I created the WIppProvLine class listed below and made a parent-child relationship between the two:
/// Used to represent a single line of IPP data
Class XFXA.MCA.WIppProvLine Extends (%Persistent, %XML.Adaptor) [ ClassType = persistent, Inheritance = right, ProcedureBlock, StorageStrategy = SQLMapping ]
{
/// .CLM_AMT_ALLOWED node: 0 piece: 6<BR>
/// This field should be used in conjunction with the Claim Operator field to
/// define a whole claim dollar amount at which a particular claim should be
/// flagged with a Pend status.
Property ClmAmtAllowed As %String;
/// .CLM_LINE_AMT_ALLOWED node: 0 piece: 8<BR>
/// This field should be used in conjunction with the Clm Line Operator field to
/// define a claim line dollar amount at which a particular claim should be flagged
/// with a Pend status.
Property ClmLineAmtAllowed As %String;
/// .CLM_LINE_OP node: 0 piece: 7<BR>
/// A new Table/Column Reference that gives the SIU (Special Investigative Unit)
/// the ability to look for claim line dollars above, below, or equal to a set
/// amount.
Property ClmLineOp As %String;
/// .CLM_OP node: 0 piece: 5<BR>
/// A new Table/Column Reference that gives the SIU (Special Investigative Unit)
/// the ability to look for claim dollars above, below, or equal to a set amount.
Property ClmOp As %String;
Property EffDt As %Date;
Property Hmo As %Integer;
/// .IPP_REASON node: 0 piece: 10<BR>
/// IPP Reason Code
Property IppCode As %Integer;
Property Keen As %Integer;
/// .LAST_CHG_DT node: 0 piece: 4<BR>
/// Last Changed Date
Property LastChgDt As %Date;
/// .PX_DX_CDE_FLAG node: 0 piece: 9<BR>
/// A Flag to indicate whether or not Procedure Codes or Diagnosis Codes are to be
/// associated with this SIU Flag Type Entry. If the Flag = Y, then control would
/// jump to a new screen where the user can enter the necessary codes.
Property PxDxCdeFlag As %String;
Property Seq As %String;
Property Seq2 As %String;
Index iMaster On (Hmo, Keen, Seq, Seq2) [ IdKey, PrimaryKey, Unique ];
/// .TERM_DT node: 0 piece: 2<BR>
/// Term Date
Property TermDt As %Date;
/// .USER_INI node: 0 piece: 3
Property UserIni As %String;
Relationship relWIppProv As XFXA.MCA.WIppProv [ Cardinality = one, Inverse = IppLines ];
Index relWIppProvIndex On relWIppProv;
//Index NewIndex1 On (RelWIppProv, Seq2) [ IdKey, PrimaryKey, Unique ];
<Storage name="SQLMapping">
<ExtentSize>1000000</ExtentSize>
<SQLMap name="DBMS">
<ConditionalWithHostVars></ConditionalWithHostVars>
<Data name="ClmAmtAllowed">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>6</Piece>
</Data>
<Data name="ClmLineAmtAllowed">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>8</Piece>
</Data>
<Data name="ClmLineOp">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>7</Piece>
</Data>
<Data name="ClmOp">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>5</Piece>
</Data>
<Data name="EffDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>1</Piece>
</Data>
<Data name="Hmo">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>11</Piece>
</Data>
<Data name="IppCode">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>10</Piece>
</Data>
<Data name="LastChgDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>4</Piece>
</Data>
<Data name="PxDxCdeFlag">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>9</Piece>
</Data>
<Data name="TermDt">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>2</Piece>
</Data>
<Data name="UserIni">
<Delimiter>"^"</Delimiter>
<Node>+0</Node>
<Piece>3</Piece>
</Data>
<Global>^WHEAIPP</Global>
<Subscript name="1">
<AccessType>Sub</AccessType>
<Expression>{Hmo}</Expression>
<LoopInitValue>1</LoopInitValue>
</Subscript>
<Subscript name="2">
<AccessType>Sub</AccessType>
<Expression>{Keen}</Expression>
<LoopInitValue>1</LoopInitValue>
</Subscript>
<Subscript name="3">
<AccessType>Sub</AccessType>
<Expression>{Seq}</Expression>
<LoopInitValue>1</LoopInitValue>
</Subscript>
<Subscript name="4">
<AccessType>Sub</AccessType>
<Expression>{Seq2}</Expression>
<LoopInitValue>1</LoopInitValue>
</Subscript>
<Type>data</Type>
</SQLMap>
<StreamLocation>^XFXA.MCA.WIppProvLineS</StreamLocation>
<Type>%Library.CacheSQLStorage</Type>
</Storage>
}
When I try to compile this one I get the following error:
ERROR #5502: Error compiling SQL Table 'XFXA_MCA.WIppProvLine
%msg: Table XFXA_MCA.WIppProvLine has the following unmapped (not defined on the data map) fields: relWIppProv'
ERROR #5030: An error occurred while compiling class XFXA.MCA.WIppProvLine
Detected 1 errors during compilation in 2.745s.
What am I doing wrong?
Thanks in Advance,
Fred
When you have parent child relationships the index declaration in the child class(XFXA.MCA.WIppProvLine) that looks like
Index iMaster On (Hmo, Keen, Seq, Seq2) [ IdKey, PrimaryKey, Unique ];
does not need the properties which are from the parent. Additional in the child class you do not declare in the class definition any property that is from the parent so you do not need in the child class
Property Hmo As %Integer;
Property Keen As %Integer;
From an OO perspective you would never set the Hmo of the Child, you set the Hmo of the parent and since the child is related it applies down the hierarchy.