We're uniting this person+holiday table with a different table of personal time off to create a general absences table. Client applications access this table through a web service in order to sync a schedule. They need a GUID on each absence entry so they know what needs to be updated. For example, if a holiday changes there's an absence for each person in that country, and the client needs to update each of those entries.

We're only sending across the absences that have been updated since the last sync, so the client can't just rebuild the whole schedule every time.

We have a table for holidays and for people. Both of these tables have a country column. Each country has a list of holidays and all the people in that country have all those holidays off. The result of the join means semantically: which people have which days off. I could create a third table for this but it would have to be updated any time a holiday or a person gets added.

 

Your suggestion of using a hash function is good, and I think I'll do that.

If the REST service is giving you JSON data, you'll have to use the Zen proxy object to consume it. Here's some documentation on how to convert JSON data to a proxy object (it doesn't actually require using Zen).

I'll add that Caché 2016.1 added some capabilities that make working with JSON much easier. See this introductory post, and this other post explaining how the syntax changed with 2016.2.

Hi Victor,

You can use the class queries  of %Library.SQLCatalog to find catalog details for tables.

The SQLTables query gives you a list of tables:

select * from %Library.SQLCatalog_SQLTables()

And the SQLFields query will give you a list of fields for a given table:

select * from %Library.SQLCatalog_SQLFields('sample table name')

You can run these queries in the command line using dynamic sql, for example:

set sql = ##class(%SQL.Statement).%New()
write sql.%PrepareClassQuery("%Library.SQLCatalog","SQLTables")
set rs = sql.%Execute()
do rs.%Display()

Hi Bob,

I've found the Terminal plugin useful for running server side code and viewing the output while I'm developing. You can dock it to the bottom of the Atelier window so it works like the Output window in Studio. The difference is that with Terminal you have to explicitly connect to the sever with SSH or Telnet. There's some relevant documentation here: https://docs.intersystems.com/atelier/latest/topic/com.intersys.eclipse....

My question is where to put the #include statement so that runtime expressions can reference the included macros. I tried both putting it in a script tag, and directly at the top of the csp file. Both ways it fails to compile with a "Referenced macro not defined" error.

EDIT - Sorry, I just noticed that was a link. The include directive should do what I need. Thanks!

Hi Bob,

For this to work you also need to define the data controller element in the page contents. For example, you could add the following element to the XData:

<dataController id="spriteController" modelClass="User.SpriteDataModel" modelId="1"/> 

If you have a data model class defined called "User.SpriteDataModel".

I recommend taking a look at the "ZENMVC.MVCForm" class in the SAMPLES namespace if you'd like an example of defining a data controller and data model.

Hi Bob,

The databag API is what the Zen MVC uses internally, you shouldn't have to worry about it.

Here's some sample code modifying the ZENTest.SVGSpriteTest sample page to display data from a datacontroller:

ClientMethod initializeCanvas() [ Language = javascript ]
{
var canvas zenPage.getComponentById('svgCanvas');
if ((!canvas) || !canvas.document) {
// ensure we don't execute code before the SVG document has been fully loaded
setTimeout('zenPage.initializeCanvas();',10);
return;
}

var inspector this.getComponentById('objectInspector');
inspector.setCurrObject(canvas);

var controller zenPage.getComponentById('spriteController');
controller.setModelId(1);
// create initial set of sprites & connectors
var sprite new Array();

sprite[0] canvas.createSprite('sprite',200,100);
sprite[0].setProperty('onclick','zenPage.selectSprite(zenThis);');
sprite[0].setProperty('caption', controller.getDataByName("sprite1"));

sprite[1] canvas.createSprite('sprite',200,300);
sprite[1].setProperty('caption', controller.getDataByName("sprite2"));
sprite[2] canvas.createSprite('sprite',400,100);
sprite[2].setProperty('caption', controller.getDataByName("sprite3"));
sprite[3] canvas.createSprite('sprite',400,300);
sprite[3].setProperty('caption', controller.getDataByName("sprite4"));

var connect canvas.createConnector('connector');
connect.addOutput(sprite[0],1);
//connect.addOutput(sprite[2],1);
connect.addInput(sprite[1],0);
//connect.addInput(sprite[3],0);

// turn off layout; turn on edit mode
canvas.setProperty('layout','');
canvas.setProperty('editMode','drag');
}

Hi Ruslan,

You can use the rowCount property of the table to find the index of the last row. But keep in mind that it's a string rather than integer, since any number greater than the maximum rows will be "100+" for example. Try using the following javascript:

var table zen("your_tablepane_id")
var rowcount parseInt(table.rowCount)
if (!isNaN(rowcount)) tablepane.selectRow(rowcount)