VersionsAll our tools should return the appropriate version details when called with the -V argument
UpgradingI'm not sure why you need a 3rd party company to look after your upgrades. There have been many upgrades since 2.11. All the documentation for our products should have two sections, a New Features section which lists the new functionality we have added (e.g. for the language
https://4js.com/online_documentation/fjs-fgl-manual-html/#c_fgl_nf.html), so you are missing out on 7 upgrades and 7 years worth of new features. There is also an Upgrade guide which lists any code changes you may have to apply to your code, sometimes we have to break things in order to move forward (e.g. for the BDL
https://4js.com/online_documentation/fjs-fgl-manual-html/#c_fgl_upgrade_guides.html). I describe these two sections, the New Features is the fun stuff to read, whilst the Upgrade Guide is the mandatory stuff to read. Also remembering that GDC, GAS, GRE etc have their own documentation with equivalent sections
You should also be aware that any day now, we start the Early Access Program, (or Beta phase) for the next release 3.0 of our products
http://4js.com/genero-version-3-0-preview/Your RequestI understand your request, I think I have requested it in the past when I was a customer. There is a new feature in 3.0 called Generic or Dynamic Dialogs. I believe something like what you have requested maybe beneficial there. However there is a way I believe you can get what you want using what is currently available.
That is to use the base.TypeInfo.create() method to convert the record into a DomNode, and do a diff on the resultant DomNode and its child elements and attributes. Have a look at the following code ...
MAIN
TYPE coordType RECORD
lat, lng DECIMAL(9,5)
END RECORD
DEFINE x1, x2 coordType
DEFINE x3 STRING
DEFINE x4 RECORD
lng, lat DECIMAL(9,5)
END RECORD
LET x1.lat = 10
LET x1.lng = 10
-- Test for same
LET x2.* = x1.*
CALL record_diff (base.TypeInfo.create(x1),base.TypeInfo.create(x2))
-- Test for different structure length
CALL record_diff (base.TypeInfo.create(x1),base.TypeInfo.create(x3))
-- Test for different structure elements
CALL record_diff (base.TypeInfo.create(x1),base.TypeInfo.create(x4))
-- Test for same structure different values
LET x2.lat = 20
CALL record_diff (base.TypeInfo.create(x1),base.TypeInfo.create(x2))
END MAIN
FUNCTION record_diff(r1,r2)
DEFINE r1, r2, f1, f2 om.DomNode
DEFINE i INTEGER
-- Check length
IF r1.getChildCount() != r2.getChildCount() THEN
DISPLAY "Record length is different"
RETURN
END IF
-- Check record structure is same
FOR i = 1 TO r1.getChildCount()
LET f1 = r1.getChildByIndex(i)
LET f2 = r2.getChildByIndex(i)
IF f1.getAttribute("name") != f2.getAttribute("name") THEN
DISPLAY "Record structure is different"
RETURN
END IF
IF f1.getAttribute("type") != f2.getAttribute("type") THEN
DISPLAY "Record structure is different"
RETURN
END IF
END FOR
-- Record structure is same, check values
FOR i = 1 TO r1.getChildCount()
LET f1 = r1.getChildByIndex(i)
LET f2 = r2.getChildByIndex(i)
IF f1.getAttribute("value") != f2.getAttribute("value") THEN
DISPLAY SFMT("Element %1 has different values %2 != %3",f1.getAttribute("name"), f1.getAttribute("value"),f2.getAttribute("value"))
RETURN
END IF
END FOR
DISPLAY "Record elements are the same"
RETURN
END FUNCTION
That should run in 2.11, base.TypeInfo.create was added in 1.33
AuditingI will point out though that if the purpose is to audit changes to certain fields, and record who changed them etc, this approach requires you being disciplined in your coding so as to ensure that every change is captured. This typically means routing calls through a single INSERT/UPDATE/DELETE, and not having any other access to your database. Another approach is to use database triggers to write to an audit table on every insert, update, delete, and these triggers can normally be generated from a database schema.
Hope that helps,
Reuben