Hi Jorge,  Thank you for the response/suggestion.  While the ZEN Report would be an option, our lab application interfaces with a reporting system that generates the report.  Our lab application provides all the report data (including images) to the reporting system.  Since the report has limited real estate for where/how the images are displayed, I was looking for a way to resize the raw images from our lab application image repository when sending the report data and images to the reporting system.   Thanks again for the feedback. 

When it comes to creating development/coding standards for your company, there are a few key things to keep in mind.  First the standards document should account for both development standards, as well as, coding standards.

Here are some thoughts/suggestions to consider:   Disclaimer:  The content listed below is just ideas and not necessarily a proposal of what your development/coding standards should be.

  1. The document should consider code that will be added/modified to existing legacy code versus new code that is being added to the application.  My recommendation for the legacy code is to insure any new code added to the legacy code try to maintain the coding style of the legacy code so the code does not become hard to read.  Example:  If the legacy code uses the old Mumps style of coding with line tags, goto, short variable names (i.e. X, Y, Z, I, J, K, PN, etc...), then I do not recommend adding Cache ObjectScript (COS) procedure blocks within the legacy code, because if added within code that contains things like structured DOs, then it could have impact on process flow, variable scoping, etc...;  If you do decide that new code (i.e. new methods) added to legacy code should follow COS standards, then consider having a coding standards rule telling programmers to add new COS style code at the end of the legacy routine - to keep all the COS style coding at the end of the routine, so the core legacy code looks consistent - it helps with reading the code for support and maintenance.   And it would be ok to allow the legacy code to call to classes/methods or to use new intrinsic functions ($Case, $Replace, etc...)
  2. The document should outline the recommended Development Standards vs. Coding Standards
    • Development Standards would be things like how to implement the various frameworks for things like error handling, database maintenance auditing, web services, handing of I/O, each definition page must have a corresponding inquiry, rules around creating custom components/composites/data types, etc...
    • Coding Standards would be things like:
      • naming conventions for packages, classes, routines, properties
      • type of comments to use
      • allow use of blank lines for readability
      • Commands should be in mixed case (or all uppercase or all lowercase - whatever is preferred for your company)
      • all Commands should be expanded (or collapsed)
      • maybe a rule about line length
      • rules around use of streams
      • rules around use of triggers
      • rules around SQL queries (dynamic? class? embedded?)
      • date/time formats
      • control structures
        • IF - comma versus double ampersand or exclamation point versus double vertical bar
        • Do-While
        • For
        • While
      • transaction processing (be careful not to mix old Mumps based TP with Cache Objects TP)
      • Should Xecute be allowed?  Can be hard to debug/support
      • Post Conditionals
      • locking (this can have information in both the development standards and the coding standards)
      • and on...
      • and on....
  3. Depending on the type of applications that your company has, there may need to be standards for the old type of UI (green screen/roll-n-scroll) versus UI for web-based applications.   There would be a whole separate list of recommendations around web-based development standards versus older Mumps based applications.
  4. When considering things such as Error Handling - there should be standards for how to deal with error handling for web-based applications, web services, and old Mumps based applications.  As you know, error handling for web-based applications can be more challenging because of the number of layers that could be involved (client, middleware (could be many layers), server (could also be many layers))
  5. Standards around database design
  6. Standards around MVC
  7. code should be modular and methods should perform a specific task.  Do not try and create methods that do everything (UI layout, validation, database updates, etc...) in a single method.
  8. There may need to be a separate standards sub-section on use of procedure blocks, since there are many things to consider when using procedure blocks
  9. and on....
  10. and on....

Any development/coding standards document could be fairly lengthy.  But as everyone can agree, standards are very important to insure applications are implemented in a consistent manner, where the code is supportable, maintainable, and reusable.  But it is also important to allow some flexibility with the standards to allow programmers the opportunity to be innovative with how they develop code.  The challenge is finding the perfect balance.

Hope this helps and Have a Great Day!!!  Go Team!!

Happy Coding!!

There are multiple options you can choose from when implementing automated actions as part of your application.  In the end, it all comes down to what solution fits best for your business use case.  Here are a few examples:

  • (automated option) You could implement a database trigger that would fire when a record is inserted or updated to your database table, where the trigger could perform some action, such as call a method to evaluate the record data and to auto-send a notification based on some business rule (i.e.  the debut date is greater than some date then auto-send the notification).  You will want to give thought to the business logic fired with the trigger to minimize performance impacts to your database transactions - but there are options for how to achieve that.
  • (automated option) You could setup a scheduled task to run at certain times of the day that would query your database table(s) for specific things and if those things (business rules) are true, then auto-send the notification
  • (manual option)  If you want a user to be the one who determines whether a notification should be sent out, then you could have a web portal application that would query your database table(s) and display key data values to the user.  Based on the data displayed, the user could manually select one or more rows and click a button or perform some action to cause the notifications to be sent.
  • and on....
  • and on....

Bottom line, it comes down to what option works best for your company/applications.

P.S.  Also, based on the size of your database tables, be sure to review the SQL Query Plans for each of your SQL Queries to insure your queries are performing optimally.  If necessary, add the appropriate indexes to the tables to help improve the query plans (and the query performance).

Hope this helps and Have a Great Day!!!   Go Team!!

Also, I recommend using caution for when the cached queries are purged "dynamically".   Purging cached queries dynamically can add risk to users running the application, such as incorrect/incomplete data and/or application errors.   It is not a good practice to purge cached queries while users are actively using the application.  If the cached query routines are deleted while a user is in the middle of having resultset data retrieved that could cause unwanted behavior.   From what I understand of Cache Database Management, things like purging of cached queries should be done during slow/down times when users are not active on the system.    Please feel free to confirm this with the InterSystems team.

Best of luck and Happy Coding....

Hi Sebastian,

If you add an  onloadHandler() method (which gets called when the page is first loaded), this method could call to the GetMessages class method to load your page property named Messages with the message content you want displayed on the page.  Then, a little later in the ZEN page creation processing when the server processing renders the ZEN page components, the <html> component will call to the DrawMessages method to load the message data on the page.

Hope this helps and Have a Great Day!!!

John

Hi Marc,

As a starting point, I recommend that you have the developers review the Cache ObjectScript (COS) documentation at the InterSystems web site:  http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls

The documentation has many reference guides and tutorials that will be helpful for any developer (new or experienced).

The developers will quickly see a lot of similar comparisons between the basic Java commands and COS commands.  Cache has various looping structures, such as For, While, and Do..While looping commands.  COS procedure blocks has local variable scoping.  COS works hand-in-hand with Cache Objects and can call class methods, instance methods, etc...

The great news is that COS is very easy to learn and use for any developer.  Also, in addition to the online Cache documentation, there is the InterSystems Cache Developer Community that has tons of wonderful information.  After your developers start using COS/Cache Objects, have them join this community, so they can ask questions about specific design or coding issues they might encounter.  There is a whole international community of Cache Developers always willing to help out.

Best of luck to you and your developers.

Best Regards,

John Hotalen

Also, you can use the built-in %RD routine.  After you enter the routine name or names that you want to see the sizes for, then answer "L" for Long Form at the next prompt.   that will display additional attributes about the specified routines - one of which will be the size in bytes.

Example Output:

                 Long Listing of Selected Routine/Include Files
                              Namespace:  TEST
                         22 Aug 2016  6:14 PM   Page 1

NAME                            .EXT.VER  LANG  DATE/TIME             #BYTES

UTTest                          .MAC            20 May 2016  10:21 am  14252
 

If you just want to see data for the class query, then you can also run the query interactively via your Cache Terminal window (or any other type of terminal emulator, such as Putty, Reflections, PowerTerm, etc...).

Here is the command to run the class query from your example:

Do ##class(%ResultSet).RunQuery("LastName.BasicClassQuery","Display")

Note:  If your query accepts input parameters, then you just include them as the 3rd-nth parameters - an example of what that might look like if you needed to pass two input values to your query:    Do ##class(%ResultSet).RunQuery("LastName.BasicClassQuery","Display","value1","value2")

This will list the data in your terminal window and might look something like this:  Notice the first row that is displayed is all your column names (i.e. property names) and all the subsequent rows that are displayed is the data from your table(s).

Code:Name:IsActive:ID:
AF:Archived Forms:1:31:
AR:AdHoc Feedback Report:1:29:
AT:Stain/Request Audit Report:1:11:
CH:Cyto-Histo Correlation:1:23:
CPS:Cytology Population Statistics:1:22:
 

Hi Benjamin,

As a fellow Cache Developer I can offer a couple of suggestions.  If you want the user to have to wait for the server side processing to complete before continuing with their work, then you could override the CSP Gateway Response Timeout:

1.  If you are working with a ZEN page (i.e. that extends from %ZEN.component.page), then you could implement an overridden version of the OnPreHyperEvent method

Example:

 /// OnPreHyperEvent - Event handler which is invoked before a hyperevent
///   method is called on all Zen pages. The purpose of this method is to
///   allow various configuration settings to be overridden prior to making
///   the actual hyperevent call (i.e. executing a query for a tablepane).
ClassMethod OnPreHyperEvent(class As %String, method As %String) As %Status [ ServerOnly = 1 ]
{
// Override the CSP Gateway Response Timeout
Set %response.Timeout={numberOfSecondsYouWantToAllowForServerProcessingToCompleteBeforeRequestTimesOut}

// Call built-in Zen Controller pre hyperevent method
Quit ##class(%ZEN.Controller).OnPreHyperEvent(..%ClassName(1),$G(method),+..#AUTONS,..#RESOURCE)
}
 

2.  If you are working with a CSP page (i.e. that extends from %CSP.Page), then you could implement an overridden version of the OnPreHTTP method

Example:

 /// Event handler for <b>PreHTTP</b> event: this is invoked before
/// the HTTP headers for a CSP page have been sent. All changes to the
/// <class>%CSP.Response</class> class, such as adding cookies, HTTP headers,
/// setting the content type etc. must be made from within the OnPreHTTP() method.
/// Also changes to the state of the CSP application such as changing
/// %session.EndSession or %session.AppTimeout must be made within the OnPreHTTP() method.
/// It is prefered that changes to %session.Preserve are also made in the OnPreHTTP() method
/// as this is more efficient, although it is supported in any section of the page.
/// Return <b>0</b> to prevent <method>OnPage</method> from being called.
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
// Override the CSP Gateway Response Timeout
Set %response.Timeout={numberOfSecondsYouWantToAllowForServerProcessingToCompleteBeforeRequestTimesOut}
Quit $$$OK
}
 

But another option to consider is to implement the ZEN page, so the user can provide the input criteria (if any) for retrieving table data and instead of having the user click a [Search] button to run the server side lookup in foreground mode (i.e. where user has to wait for the server processing to complete), you could instead implement a [Run In Background] button where you job off the server side processing, so it can run in the background, which allows the user to do other things with the application and they can check back at a later point for the status.   You could have some type of mechanism on the ZEN page that shows the user the status of the background process (i.e. Running, Completed, Error, etc...);   You can refer to the built-in  %RunBackgroundMethod method or you could implement your own application specific background type processing - example:  As the user submits various background jobs to run, you could have a tablepane display the various processes that are running with their status - then when complete, you could have a link in that table the user could click to display the associated data that was retrieved from the server.

Hope this helps and Have a Great Day!!    Happy Coding!