I have some ideas which I'm going to implement.
Do you know if there is a way to determine inside the trigger when it's the last record to replace, if, say, we're using replace next 500 command?
>hi Nadya,
>
>Let's take a fresh start
>
>(1) you have one entry point for all triggers, say Trigger(TableName, TriggerType) (create trigger on tablename ...)
>this one, if triggerlevel = 1 initiates a transaction (since 4 or 5 levels are the maximum) and either ends it or rolls it back depending on success or failure
>
>(2) each routine that is called returns success or failure
>
>(3) the entry point in (1) must decide what to do. You'll need the info from adbobjects (ths scan) and some index expressions
>There is no need to fetch them every time, since they are static (until you change the RI of course)
>
>You can either hard code them (like the standard RI) or put them in an internal free table
>
>If you put them in a free table, you can select into array and then eval(array[ i ] ) in for/next
>
>Hard coding them is not really that hard, it is a succession of (a-f) below
>
>Maybe you can start with an internal free table for a start and when all is debugged, generate the code for the RI
>
>Like I wrote in a message once there are only a few scenarios possible (my function names follow, self explanatory)
> ** analyse Doug's code and try to come to the same conclusion
> (a) _Trigger_Process_Relation_Parent_Delete_Restrict
> (b) _Trigger_Process_Relation_Parent_Delete_Cascade
> (c) _Trigger_Process_Relation_Parent_Update_Restrict
> (d) _Trigger_Process_Relation_Parent_Update_Cascade
> (e) _Trigger_Process_Relation_Child_Insert_Restrict
> (f) _Trigger_Process_Relation_Child_Update_Restrict
>
>So each trigger that fires may have zero or more of the above.
>Each one of the above returns Success or failure.
>When there is a failure, you skip the next (if any) and return Failure
>
>Each of the is called with certain parameters
>I have this
>
>#define TRIGGERRELATION_PARAMETERLIST ;
> thisTable, thisIndexExpr, OtherTable, OtherTag, OtherIndexExpr
>
>
>and for (d) above
>
>lparameters TRIGGERRELATION_PARAMETERLIST, CascadeReplaceCommand
>
>
>An example of a replace command
>
>replace il_inv_id with ?.inv_id, il_inv_y_id with ?.inv_y_id
>
>you strtran(CascadeReplaceCommand, '?', alias())
>
>&CascadeReplaceCommand
>
>
>Each one of the above (a-f) will re-open tables and close them upon exit
>You can use functions (triggeropen/triggerclose) and cache them (see standard RI)
>
>Prior to (1) exiting, hard-close the cached aliases
>
>
>You have all the bits and pieces you need
>
>So, if I were you I would start by making a table or a cursor with all tables and the indexes (basically taginfo)
>some thing like
>
>create cursor TableInfo ( ;
> Database c(15), ;
> Table c(128), ;
> TagType c(1), ;
> Tag c(15), ;
> Expression M, ;
> Filter M, ;
> Collate c(9), ;
> Descending L, ;
> FieldList M ;
>)
>
>
>The FieldList is a list of fields that are in the index expr
>I use this to get them (not foolproof), but hey it's all that I need
>
>#define NL chr(0x0a)
>function FieldListFromExpression( s, TableAlias )
> local i, n, out, expArray[1]
>
> TableAlias = iif(!empty(m.TableAlias), m.TableAlias, select(0))
>
> #define sep [!@#$%^&*()-+=></,"]
> for i = 1 to len(sep)
> s = strtran(m.s, substr(sep, m.i,1), NL)
> endfor
> #undefine sep
>
>
> n = alines(expArray, m.s, TRUE )
>
> Out = ''
> for i = 1 to n
>
> do case
> case empty(expArray[m.i])
>
> case empty(fsize(expArray[m.i], m.TableAlias))
>
> case !empty(m.out)
> Out = m.out + ',' + expArray[m.i]
>
> otherwise
> Out = expArray[m.i]
>
> endcase
> endfor
> return Out
>endfunc
>*---------------------------------------------------------------------------
>
>
>Then, (using adbobjects('relation') make a cursor with
>
>
>- Table
>- seq I
>- an action (a-f) above
>- IndexExpr
>- OtherTable
>- OtherTag
>- OtherIndexExpr
>- replacecommand (in case of _Trigger_Process_Relation_Parent_Update_Cascade)
>
>
>
>It will become much clearer then
>
>
>Your are now ready to re-invent the wheel ;-)
If it's not broken, fix it until it is.
My Blog