Joost Verhoog wrote:

Is there any way to automatically convert Foreign Keys to Relationships?


Well, I just did something like this with a parent/child relationship,
and it Worked For Me(tm), but it's writing to low level data structures, so all of the usual caveats apply-- meaning, you can certainly trash your data beyond all repair, and I very well may be missing something
because I'm not a system programmer. Plus, underlying data structures changed a few times over the last few years, what I did was with 5.0.9,
using globals that date back to Cach� 3.1.2, YMMV. So, back up
everything first, OK?


You probably already have data in two different globals. So you take out the property that's a foreign key, add
your relationship and compile your classes. Then, do a query
and YOU GET NO ROWS! Because all the underlying data is in the old
format. So, now you need to reformat your data.


Let's say that your old data structure had your foreign key in the first
position, but if you add a test record, you see in Explorer
it stores the parent as in the first level and the id as the second level. So we write a routine to change things around.


In the case my parent class is Businesses and my child class PINs,

MangleMyData
  S oldPINId=""

  While $O(^ooPINsD(oldPINId))'="" {
        Set oldPINId=$O(^ooPINsD(oldPINId))
        Set PINPropList=^ooPINsD(oldPINId)
        
        Set BusinessId=$LG(PINPropList,1)
        
        ;remove first item from list - this was business id
        Set PINPropList=$LI(PINPropList,2,$LL(PINPropList))

        ;kill old node
        Kill ^ooPINsD(oldPINId)
                
        ;write list to ^ooPINsD(<business>,<pbx>,<oldid>)
        ;If child data stored in its own global, should look like this
        ;^ooPINsD(1,370760)=<<$LB("11111","59758","","","4","","")>>
        Set ^ooPINsD(BusinessId,oldPINId)=PINPropList

        ;this would be if parent and child stored in same global
        ;S ^ooBusinessesD(BusinessId,"PINs",PINId)=PINPropList

        ;fix up old references to old id
        ;this is the way that SQL will want to see the new IDs
        Set newPINId=BusinessId_"||"_oldPINId

        &sql(update accounts set PIN = :newPINId where PIN = :oldPINId)

  }

  ; have the system recreate the indexes that would have been added
  ; automatically if I was using SQL
  Do ##class(PINs).%BuildIndices("")

  Quit

After running this, you should be able to do queries again.

HTH

Dave



Reply via email to