Stefan Wittmann · Feb 17, 2016 go to post

Scott,

the INFORMATION_SCHEMA sample works with pure SQL. Just run the query and substitute parameters:

select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_SCHEMA = ? and TABLE_NAME = ?

Tim just wrote a COS wrapper to output the column names as a string. 

Stefan Wittmann · Feb 17, 2016 go to post

What Eduard means is that you can create a registered class, with typed properties (a boolean and a numeric in your case), populate it and then transform to JSON using the jsonProvider.

That is the only valid approach to control JSON types in versions before 2016.1. Everything else is a hack.

Stefan Wittmann · Feb 17, 2016 go to post

Thanks Eduard for posting the working solution. The reason why this works is that you actually create an object of your registered class and assign the values. The jsonProvider API can now walk the object and project the types properly.

In the non-working example, you created a zenProxyObject and assigned the values on your own. The zenProxyObject just deals with auto-types and guesses the best possible type fit. As you see, this guess can't be correct all the time as in this case.

If you want to create a JSON structure with specific types, either use a) the new JSON support in 2016.1 (recommended if 2016.1 is available) or b) create a subclass from %RegisteredObject and use the jsonProvider API.

Stefan Wittmann · Feb 17, 2016 go to post

You can define quoted property names, e.g.:

Property "not_a_number" As %String;

same for runtime properties:

set object."not_a_number" = "28456"

Stefan Wittmann · Feb 26, 2016 go to post

Sounds like a use case for a DTL if you ask me. Even if it's not and you have to be very generic, I would start with a DTL and take a look at the compiled code as a starting point. 

Stefan Wittmann · Feb 26, 2016 go to post

For the moment, I subscribed to all group and post activity in my subscription tab. Make sure to select "content types". This way I get a mail for any activity, which can be noisy, but at least, I am sure I am not missing anything.

I hope for better days. ;)

Stefan Wittmann · Mar 3, 2016 go to post

I have played with Visual Studio Code, but at its core, it is nothing more than a smart text editor like TextMate2 with some extensions for running tasks. It includes the runtime and can, therefore, add a debugger, which is nice. But it is not a full blown IDE.

VS Code has a user group, but it is not build to allow more complex workflow integration, which is something Atelier wants to offer at some point.

I am sure Bill can provide more insight. 

Stefan Wittmann · Mar 3, 2016 go to post

Projections are indeed very powerful. A use case within the product is the generation of JavaScript, CSS and localization files when you compile a Zen or Zen Mojo page.

Projections are a good tool if you have to do something every time you compile a class.

Stefan Wittmann · Mar 4, 2016 go to post

John,

I just tried the link and it worked fine for me. I guess it took a while to get published for real. Sometime the cache is just in the way.

Please try again,

Stefan

Stefan Wittmann · Mar 4, 2016 go to post

Just as a note, this is something you would usually tackle with a gulp or grunt task, e.g. 

https://www.npmjs.com/package/gulp-minify

These watch external files and run a task every time they change. This means a gulp/grunt task can minify JavaScript files after you compiled your Zen/Zen Mojo classes.

Stefan Wittmann · Mar 4, 2016 go to post

A couple of years ago I built my own UML class diagram viewer, but it was more for the fun of it. I just like to visualize relationships and workflows as I believe it helps the mind to understand complex entities better.

There is a UML Explorer tool available at this GitHub repo:

https://github.com/intersystems-ru/UMLExplorer

Stefan Wittmann · Mar 8, 2016 go to post

Dropdownmenuitems did not attach event handlers when a key is present, which is a bug. This is fixed in the next release Zen Mojo 1.1.1. The new version is currently verified by QD, so you can expect a release within the next 2 weeks.

Stefan Wittmann · Mar 8, 2016 go to post

Hi Benjamin,

regarding your questions:

1) String concatenation is possible with the underscore "_" character. For example:

set myquery = "SELECT * FROM " _ tableName

Don't use the plus "+" character as this is the addition operator. It will evaluate your string and convert it into a number. Unless your string starts with a number, it will be evaluated to 0. 

2) Multiline statements are not supported in Caché Object Script, so you have to concatenate your string if you want to spread the query on multiple lines.

HTH,

Stefan

Stefan Wittmann · Mar 9, 2016 go to post

Jochen, this code will only work if the template dispatch mode is enabled. If you are running in standard mode, this is the code you need to make the sample work:

ClientMethod StartEvent(
key,
eventType,
value) [ Language = javascript ]
{
var st = zenPage.getTemplate();
st.[eventType](key,value,'mainView');
}
Stefan Wittmann · Mar 11, 2016 go to post

%Library.Result is the old SQL interface and it is recommended to use the new interface %SQL.Statement. %SQL.Statement is capable of providing metadata about the result set and performs better than the old interface in many cases.

Stefan Wittmann · Mar 11, 2016 go to post

Well, that obviously depends on how good your owl logic is. wink  I only recommend this approach if the standard interface is insufficient for a specific need and you have to optimize further. 

Writing your own logic does not leverage optimizations from newer versions and you have to maintain it.

A major benefit of %SQL.CustomResultSet is that you can query any accessible data source, e.g. globals and files.

Stefan Wittmann · Mar 11, 2016 go to post

Again, it depends on what you are comparing to. Just looping over a global can be compared to a simple full table scan and the runtime performance should be pretty much the same.

If you have a complex query that can't be boosted by adding just another index or by running tune table, you can probably write your own custom logic. An even better solution is to implement a custom index that can be leveraged by SQL.

You have to keep in mind that the %SQL.CustomResultSet approach does not lead to reusable code. It can be used to solve a very specific problem, but it can't be reused for a similar problem on a different data set.

Stefan Wittmann · Mar 15, 2016 go to post

Correct, bandwidth is not so much of an issue. Latency can be an issue as a high latency will make all actions that require server interaction be perceived slowly.

Also, you should be aware that Studio runs a server status check on a regular basis by default. If your latency or connection is bad you should increase the timeouts, otherwise, you will see a popup asking for a reconnection pretty often. The setting can be found here: Tools->Options, go to Environment->Advanced and take a look at the "Enable server status check" setting.

Stefan Wittmann · Apr 1, 2016 go to post

Also, if you are using the System Management Portal to activate a new key, make sure to double check the capabilities of the new key. You will be presented with a popup that displays the new key, so you can make sure that you really selected the correct key for activation (e.g. correct platform, all required features).

Activating a new key does not require a system restart unless there are major differences between the old and the new key. As an example: If the new key enables the same number of users (or more) a restart is not required. Downgrading the user count will require a system restart. 

Stefan Wittmann · Apr 1, 2016 go to post

Ha, this post really made me laugh out loud. But I do see use cases for this kind of an integration. If you use slack for issue tracking you can easily create  a channel where all Ensemble issues are automatically posted. Inactive Business Services, thrown errors, etc. If Slack is part of your company culture, this is a simple and nice enhancement to your workflow. 

Stefan Wittmann · Apr 1, 2016 go to post

I used the Google Geocode API some while ago and if you call it occasionally you won't see any issues. If you want to bulk load some data and attach lat/long values during that process you have to queue your requests to Google. They only allow 3~4 requests per second for each API key otherwise, you will get a bad response.

Stefan Wittmann · Apr 1, 2016 go to post

I think you have to manually resort the CacheTemp global into another location based on the sortColumn and sortOrder properties of your table. Some work, but doable. Timothy provided some insight to that approach.

Stefan Wittmann · Apr 7, 2016 go to post

I am not sure I understand your question. Do you want to subclass from %Object and %Array? If so for what purpose?

Stefan Wittmann · Apr 7, 2016 go to post

I just tested this in a 2016.2 FieldTest terminal session:

USER>set object = {"":"test"}
 
USER>w object.$toJSON()
{"":"test"}
USER>set object."" = "one more test"
 
USER>w object.$toJSON()
{"":"one more test"}

So the answer is, yes we do support empty keys.

We have and continue to test our JSON implementation heavily. If you come across anything that looks incomplete, incorrect or just behaves in unexpected ways, let us know. We are happy to take a look at it.

Many thanks, Stefan

Stefan Wittmann · Apr 7, 2016 go to post

Absolutely. If you are using the embedded JSON-style constructor you can directly make use of special values:

USER>set object = {"boolean":false,"numeric":2.2,"nullValue":null}
 
USER>write object.$toJSON()
{"boolean":false,"numeric":2.2,"nullValue":null}

If you want to manipulate or add special values like null and true/false, you have to use the setter method $set and specify the type with the optional third argument:

USER>do object.$set("anotherBoolean",1,"boolean")
 
USER>write object.$toJSON()
{"boolean":false,"numeric":2.2,"nullValue":null,"anotherBoolean":true}
If I wouldn't have specified the type in the above sample, the value would have been set to the numeric value 1.
HTH,
Stefan