Maybe is obvious to people but the downside to encryption is that if you lose your encryption keys, you lose all of your encrypted data. That would be ironic if the reason you encrypted your data was to prevent data loss and theft. This fear of data loss has been the key driver for not using key-based encryption within our applications - even though there are good business reasons for doing so.

No more certificate errors. I believe the issue with the certificate is now resolved.

Hi Marco,

I think your problem might be to do with having declared 'TotalMatrix' as a transient property, it does not exist in the 'Relations' table. In my example, I referenced a table class called 'ZenTutorial.PhoneNumber' but my SQL statement did NOT refer to a 'TotalPhones' column.

Consider this

colExpression="(select count(*) from ZenTutorial.PhoneNumber where Contact=ZenTutorial.Contact.ID)"

So the result of the SQL goes into my TotalPhones column on my tablePane but the ZenTutorial.PhoneNumber class does not recognise it as a SQL field. Transient properties are useful when opening %Persistent objects and dynamically setting the transient property at the %OnOpen() event based on a set of conditions. As TotalPhones is marked as transient, it is not stored in the Global Mapping for %Library.CacheStorage. You cannot reference it in your SQL statement.

What if you tried something like

SELECT COUNT(*) AS TotalMatrix FROM Relations

You will need all those relationships in there though for it to work. If you have a <column> section defined in your tablePane be sure to set colName="TotalMatrix"

I hope that helps.



Nope, certificate error still remains. Our web security policy blocks access to sites with certificate errors.

Error details are as follows

VERIFY DENY: depth=0, CommonName "*" does not match URL ""

This is excellent! Probably the best answer on this question. I would add that sometimes the process is the login session of an individual user and what the user does within that session needs to be carefully managed!

You can also use set $ZS=1234567 to set the max-limit memory for your process. Useful if the default memory is inadequate for a particular process but is fine for everything else.

Thanks Wolf Koelling.  I should have made it more explicit that %vars are shared across NAMESPACES not processes. When a user logs into our system their process remains active as long as they are logged in. During their login session they can call any number of COS routines to perform a wide range of different functions. Variables not explicitly killed off still reside in memory and this was the problem I had to solve. 

I had to be sure that

a) The %ZLOG COS routine would not crash out because of missing variables the routine expects.

b) All the calls or entry points into %ZLOG would still work as normal otherwise a system-wide crash would occur across all our databases.

c) Be able to identify that if my background process had called %ZLOG then use the PPG created before the call to %ZLOG. No other code in our system uses PPGs whereas there is a plethora of globals, %variables and non-percent variables. 

I could have used a scratch or temporary global such as ^CacheTempUser.DataExtract($JOB). This type of global is killed off when the instance is brought down for our daily backup job. A PPG was very easy to implement.

I have placed a strikethrough on the erroneous statement in my answer.

Ok, I *think* I have it now.

ClientMethod onSelectRow() [ Language = javascript ]
	var resultsPane=zenPage.getComponentById('resultsPaneId');
	var isHidden=resultsPane.getHidden();

	if (!isHidden)
		var table=zenPage.getComponentById('workBioTable');
		var dataRow=table.getRowData(table.selectedIndex);

	if (dataRow)
		var rowID = zenPage.GetSelectedRowId(dataRow.RequestDate,dataRow.Worksheet,dataRow.SpecId);

		if (rowID)
			var waittoend = zenPage.GetAuditLogs(rowID);

} // end-if

Note the variable 'waittoend' and the zenPage.GetAuditLogs(RowId) method. This process builds the global that the secondary tablePane is built from. Without the return value, it is possible for the table to refresh before the global is built for the newly selected row.

Testing this has been difficult because in the most cases, the table was displayed correctly but several dozen clicks later you gasp, "Did I just see that!?" when you notice that on this one occasion it did not update correctly.