Event "BeforeDeleteInstance"Event "BeforeDeleteInstance"RE: Event "BeforeDeleteInstance"Wilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=3930042015-10-27T11:59:18Z2015-10-27T11:59:18ZAs an update to the previous implementation proposal, please consider the following update. It is discouraged to use the "UpdateAction" event as this could result in unpredicted behaviour. The approach for preventing relation instances to be deleted, we can combine the "DeleteRelationInstance" with "DiscardRelationInstance". The approach is based on the sequence of events, as during the <strong>DeleteRelationInstance</strong> we can capture the deleted relation and all available attributes, serialize this information and run a re-create in the <strong>DiscardRelationInstance</strong>, as this event is triggered when the relation instance is discarded from the modelling core.<br /><br />The proposal below builds upon this assumption, serialization between the events is realized using a map object, e.g. serializing in memory.<br /><br /><div class="code"><span class="code-lines">1</span>ON_EVENT "AppInitialized"<br /><span class="code-lines">2</span>{<br /><span class="code-lines">3</span> # ...<br /><span class="code-lines">4</span> SETG mDeletedRelations: (map())<br /><span class="code-lines">5</span> # ....<br /><span class="code-lines">6</span>}<br /></div>During AppInitialized, the map for serializing is initialized.<br /><br /><div class="code"><span class="code-lines"> 1</span>ON_EVENT "DeleteRelationInstance" {<br /><span class="code-lines"> 2</span> IF (( #select the appropriate instance type#)) {<br /><span class="code-lines"> 3</span> # get the position of the relation <br /><span class="code-lines"> 4</span> CC "Core" GET_ATTR_VAL objid: (relationinstanceid) attrname:"Positions"<br /><span class="code-lines"> 5</span> SETL sPositionsVal: (val)<br /><span class="code-lines"> 6</span> # get all attributes of the relation<br /><span class="code-lines"> 7</span> CC "Core" GET_ALL_ATTRS classid: (relationclassid)<br /><span class="code-lines"> 8</span> SETL lAttributeIDs: (attrids)<br /><span class="code-lines"> 9</span> SETL lAttributeMap: ("")<br /><span class="code-lines">10</span> FOR sAttributeID in: (lAttributeIDs) {<br /><span class="code-lines">11</span> CC "Core" GET_ATTR_VAL objid: (relationinstanceid) attrid: (VAL sAttributeID) as-string<br /><span class="code-lines">12</span> SETL sAttributeValue: (val)<br /><span class="code-lines">13</span> SETL sIDValuePair: (sAttributeID + "#" + sAttributeValue)<br /><span class="code-lines">14</span> SETL lAttributeMap: (tokunion (lAttributeMap, sIDValuePair, "|"))<br /><span class="code-lines">15</span> }<br /><span class="code-lines">16</span> IF (type (mDeletedRelations[id_componentid]) = "undefined") {<br /><span class="code-lines">17</span> SET sTimeStampedDeletedActions: (STR relationclassid + "|" + STR toinstanceid + "|" + STR frominstanceid + "|" + base64encode(sPositionsVal) + "|" + base64encode(lAttributeMap)+ "|" + STR relationinstanceid)<br /><span class="code-lines">18</span> }<br /><span class="code-lines">19</span> ELSE {<br /><span class="code-lines">20</span> SET sTimeStampedDeletedActions: (tokunion (mDeletedRelations[id_componentid], STR relationclassid + "|" + STR toinstanceid + "|" + STR frominstanceid + "|" + base64encode(sPositionsVal)+ "|" + base64encode(lAttributeMap) + "|" + STR relationinstanceid))<br /><span class="code-lines">21</span> }<br /><span class="code-lines">22</span> SETG mDeletedRelations[id_componentid]: (sTimeStampedDeletedActions)<br /><span class="code-lines">23</span>}<br /></div>The "DeleteRelationInstance" retrieves the values from the deleted relation and stores them into the map element<br /><br /><div class="code"><span class="code-lines"> 1</span>ON_EVENT "DiscardRelationInstance" {<br /><span class="code-lines"> 2</span> CC "Modeling" GET_ACT_MODEL<br /><span class="code-lines"> 3</span> SETL nCreatedModelID: (modelid)<br /><span class="code-lines"> 4</span> IF (nCreatedModelID != -1 AND LEN (mDeletedRelations) > 0) {<br /><span class="code-lines"> 5</span> FOR sDeletedRelation in: (mDeletedRelations) {<br /><span class="code-lines"> 6</span> IF (LEN (sDeletedRelation) > 0) {<br /><span class="code-lines"> 7</span> EVENT_LOG msgType:"EVENT_LOG" message: (sDeletedRelation)<br /><span class="code-lines"> 8</span> CC "Core" CREATE_CONNECTOR modelid: (modelid) fromobjid: (VAL token (sDeletedRelation, 2, "|")) toobjid: (VAL token (sDeletedRelation, 1, "|")) classid: (VAL token (sDeletedRelation, 0, "|"))<br /><span class="code-lines"> 9</span> SETL nNewRelationID: (objid)<br /><span class="code-lines">10</span> CC "Core" SET_ATTR_VAL objid: (nNewRelationID) attrname:"Positions" val: (base64decode(token (sDeletedRelation, 3, "|")))<br /><span class="code-lines">11</span> SETL lAttributeValueMap: (base64decode(token (sDeletedRelation, 4, "|")))<br /><span class="code-lines">12</span> FOR sAttributeKeyValue in: (lAttributeValueMap) sep:"|" {<br /><span class="code-lines">13</span> SET sAttributeID: (token (sAttributeKeyValue, 0, "#"))<br /><span class="code-lines">14</span> SET sAttributeValue: (token (sAttributeKeyValue, 1, "#"))<br /><span class="code-lines">15</span> CC "Core" GET_ATTR_TYPE attrid: (VAL sAttributeID)<br /><span class="code-lines">16</span> IF (attrtype = "INTEGER" OR attrtype = "DOUBLE" OR attrtype = "TIME") {<br /><span class="code-lines">17</span> CC "Core" SET_ATTR_VAL objid: (nNewRelationID) attrid: (VAL sAttributeID) val: (VAL sAttributeValue)<br /><span class="code-lines">18</span> } ELSE {<br /><span class="code-lines">19</span> CC "Core" SET_ATTR_VAL objid: (nNewRelationID) attrid: (VAL sAttributeID) val: (sAttributeValue)<br /><span class="code-lines">20</span> }<br /><span class="code-lines">21</span> }<br /><span class="code-lines">22</span> }<br /><span class="code-lines">23</span> }<br /><span class="code-lines">24</span> # reset map<br /><span class="code-lines">25</span> SETG mDeletedRelations: (map())<br /><span class="code-lines">26</span> }<br /><span class="code-lines">27</span>}<br /></div>The event "DiscardRelationInstance" is used to re-create the missing connector.Wilfrid Utz2015-10-27T11:59:18ZRE: Event "BeforeDeleteInstance"Wilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=1759542014-09-30T11:39:32Z2014-09-30T11:39:32ZHi Domenik,<br /><br />to prevent the deletion of instances (NOT relation instances), you can just EXIT the event with -1 and you are good. See a small example below.<br /><br /><div class="code"><span class="code-lines">1</span>ON_EVENT "BeforeDeleteInstance" {<br /><span class="code-lines">2</span> # your custom logic, if not done, no deletion is possible at all<br /><span class="code-lines">3</span> EXIT -1<br /><span class="code-lines">4</span>}<br /></div>Wilfrid Utz2014-09-30T11:39:32ZRE: Event "BeforeDeleteInstance"Dominik Borkhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=1748432014-09-25T12:24:49Z2014-09-25T12:24:49ZDoes the same limitation hold for the object deletion or is there a way to prevent ADOxx from deleting modeling class instances?<br /><br />Thank you.<br />- DomenikDominik Bork2014-09-25T12:24:49ZEvent "BeforeDeleteInstance"Wilfrid Utzhttps://www.adoxx.org/live/c/message_boards/find_message?p_l_id=&messageId=187212015-10-28T07:28:49Z2013-04-11T18:31:02Z<strong><span style="font-size: 18px"><span style="color: #b22222">NEW APPROACH DESCRIBED IN FOLLOWING POST - Use of EVENT UpdateAction is discouraged!</span></span></strong><br /><br />Currently, the "BeforeDeleteInstance" deletes related connectors, even if the event is cancelled, meaning the EXIT value is set to -1. This is due to the fact, that the deletion of events is happened beforehand. To overcome this limitation, the following implementation can be used. This is actually a restore mechanism of relation instances after the delete.<br /><br />- Implement a stack of deletedRelations as a map with the deleted relations and the related timestamp as a key, that is only updated in case the event triggering the delete is from the BeforeDeleteInstance event<br />- Implement the UpdateAction event inclduing a trigger flag (otherwise the event is triggered continously.<br />- Implement a timestamp capture mechanism to realize the events that should be restored.<br /><br /><br />Limitations:<br />- attribute values are currently not captured, this would to be implemented on a custom/method level<br /><br /><div class="code"><span class="code-lines"> 1</span>ON_EVENT "AppInitialized" {<br /><span class="code-lines"> 2</span> # init the holder for deleted relations as a map and the event time when these where triggered<br /><span class="code-lines"> 3</span> SETG mDeletedRelations: (map())<br /><span class="code-lines"> 4</span> SETG sEventTime:""<br /><span class="code-lines"> 5</span> ...<br /><span class="code-lines"> 6</span>}<br /><span class="code-lines"> 7</span><br /><span class="code-lines"> 8</span>ON_EVENT "BeforeDeleteInstance" {<br /><span class="code-lines"> 9</span> CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"<br /><span class="code-lines">10</span> #... [other code to determine whether the EXIT is set to -1<br /><span class="code-lines">11</span> # set the flag only if the delete of the instance comes from a cancelled delete of objects<br /><span class="code-lines">12</span> IF (execResult = -1) {<br /><span class="code-lines">13</span> SETG bUpdate: (1)<br /><span class="code-lines">14</span> SETG sEventTime: (time)<br /><span class="code-lines">15</span> } <br /><span class="code-lines">16</span> ELSE {<br /><span class="code-lines">17</span> SETG bUpdate: (0)<br /><span class="code-lines">18</span> }<br /><span class="code-lines">19</span> EXIT (execResult) <br /><span class="code-lines">20</span>}<br /><span class="code-lines">21</span><br /><span class="code-lines">22</span>ON_EVENT "DeleteRelationInstance" {<br /><span class="code-lines">23</span> CC "Application" GET_DATE_TIME date-format:"dd/mm/yyyy" time-format:"hh:mm:ss"<br /><span class="code-lines">24</span> # store all parameters so that they are available in other action, for restore<br /><span class="code-lines">25</span> IF (type (mDeletedRelations[time]) = "undefined") {<br /><span class="code-lines">26</span> SET sTimeStampedDeletedActions: (STR relationclassid + "|" + STR toinstanceid + "|" + STR frominstanceid)<br /><span class="code-lines">27</span> }<br /><span class="code-lines">28</span> ELSE {<br /><span class="code-lines">29</span> SET sTimeStampedDeletedActions: (tokunion (mDeletedRelations[time], STR relationclassid + "|" + STR toinstanceid + "|" + STR frominstanceid))<br /><span class="code-lines">30</span> }<br /><span class="code-lines">31</span> SETG mDeletedRelations[time]: (sTimeStampedDeletedActions)<br /><span class="code-lines">32</span> # TODO: add attribute value collecting functionality<br /><span class="code-lines">33</span>}<br /><span class="code-lines">34</span><br /><span class="code-lines">35</span>ON_EVENT "UpdateActions" {<br /><span class="code-lines">36</span> # only if flag is there<br /><span class="code-lines">37</span> IF (bUpdate) {<br /><span class="code-lines">38</span> # reset flag<br /><span class="code-lines">39</span> SETG bUpdate: (0)<br /><span class="code-lines">40</span> IF (type (mDeletedRelations[sEventTime]) <> "undefined") {<br /><span class="code-lines">41</span> FOR sDeletedRelation in: (mDeletedRelations[sEventTime]) {<br /><span class="code-lines">42</span> # only do if the timestamp contains a value<br /><span class="code-lines">43</span> CC "Core" CREATE_CONNECTOR modelid: (modelid) fromobjid: (VAL token (sDeletedRelation, 2, "|")) toobjid: (VAL token (sDeletedRelation, 1, "|")) classid: (VAL token (sDeletedRelation, 0, "|"))<br /><span class="code-lines">44</span> }<br /><span class="code-lines">45</span> # reset the list of deletedRelations<br /><span class="code-lines">46</span> SETG mDeletedRelations: (map())<br /><span class="code-lines">47</span> # TODO: add functionality to restore attribute values.<br /><span class="code-lines">48</span> }<br /><span class="code-lines">49</span> }<br /><span class="code-lines">50</span>}<br /></div>Wilfrid Utz2013-04-11T18:31:02Z