Some options:

> - Utilize another language or library that has methods to parse the data into an Excel file (https://stackoverflow.com/questions/17684610/python-convert-csv-to-xlsx).

If you want to use Python from Cache, check PythonGateway.

Mimedata is subscripted by name and index.

So in your case:

set name = "BulkFileUpload"
for i=1:1:%request.CountMimeData(name)
    set mimeData = %request.GetMimeData(name, , i)
}

On each iteration mimeData variable would hold the stream with one next mimedata.

%request is simply an object of %CSP.Request class, check the docs or code to know how it works.

Additionally you can use this snippet to see what's inside %request, %response and %session objects:

set %response.ContentType = "html"
do ##class(%CSP.Utils).DisplayAllObjects()
quit $$$OK

Bitmap indices maintain one node per each chunk of 64 000 id's, if at least one id from that range exists. So random integer ids can slow bitmaps down. On the other hand if there are two consecutive but spread (i.e 1..1000 and 100000...110000) id sequences it would generate just 2 global nodes so everything should be ok in that scenario.

Check index global in various scenarios:

 
Example.Bitmap

Eduard, are you referring to the Priority property of the Ens.MessageHeader class?

Yes.

That seems to be used exclusively for marking the message for Async vs. Synchronous delivery.

These priorities are available:

#define eMessagePriorityHighSync 1
#define eMessagePrioritySync     2
#define eMessagePrioritySimSync  4
#define eMessagePriorityAsync    6

Sync by default is 2, so specifying priority 1 may indeed help. Cursory glance at Ens.Queue indicates that messages with priority 1 would be processed first.

But this also means that you can't ship the whole vendor copy of the global as you will overwrite the onsite ID counter node.

You can! When you load globals specify /mergeglobal flag to merge the global with existing data instead of overwriting it:

set sc = $system.OBJ.Load("global.xml", "/mergeglobal=1")

seed the ID counter at the site to a really high number

Bitmap indices would really slow down from that.

This applies to properties of a class correct? Not just methods?

Correct.

You have several solutions:

  1. Application level control. You have one table Term { Name, Type} and on the application level you decide for edits to go or not based on type. It is the fastest solution, but you need to write a application code and remember to check for type.
  2. Class-level control as described by you.
  3. Row-level security. Control access row by row.

The easiest way is to use JSON_OBJECT for everything. Fastest would be just writing to device from resultset. Combine these approaches to get the performance you need (add this code to Parent class and call Test method):


Query Display() As %SQLQuery
{
SELECT
    JSON_OBJECT(
        'ID':%ID,
        'Name': Name,
        'Description': Description,
        'Children':    Example.Parent_GetChildrenInfo(%ID)
    )
FROM Example.Parent
}

/// do ##class(Example.Parent).Test()
ClassMethod Test(count = 0)
{
    if count>0 {
        do ##class(Example.Child).%KillExtent()
        do ..%KillExtent()
        
        
        do ##class(Example.Child).Populate(count,,,,$$$NO)
        do ..Populate(count,,,,$$$NO)
    }
    
    do ..DisplayFunc().%Display()
}

ClassMethod GetChildrenInfo(id) As %String [ SqlProc ]
{
    #define CRLF                             $c(13,10)
    #define ZENJSISNUM(%val)                ($IsValidNum(%val)&&(%val=+(%val)))
    #define ZENJSNUM(%num)                    $fnumber(%num,"LON")
    #; JSON utility macros that use the JSON translation table instead of the JS translation table
    #define ZENJSTABLE(%format)                ("JS"_$S(%format["u":"ML",1:""))
    #define ZENJSONTABLE(%format)            ("JSON"_$S((%format["u"):"ML",1:""))
    #define ZENJSONESCAPE(%str,%format)        $S(%format["s":$ZCVT(%str,"O",$$$ZENJSONTABLE(%format)),1:$Replace($ZCVT(%str,"O",$$$ZENJSTABLE(%format)),"\'","'"))
    #define ZENJSONSTR(%str,%format)        (""""_$$$ZENJSONESCAPE(%str,%format)_"""")
    #define ZENJSONPROP(%prop,%format)        $$$ZENJSONSTR(%prop,%format)
    #define ZENJSONVALUE(%val,%format)        $S($$$ZENJSISNUM(%val):$$$ZENJSNUM(%val),$C(0)=(%val)||$ListValid(%val):"""""",1:$$$ZENJSONSTR(%val,%format))
    #define ZENJSONPAIR(%pr,%val,%format)    $$$ZENJSONPROP(%pr,%format)_":"_$$$ZENJSONVALUE(%val,%format)
    
    set out = "["   
    
    
    set ids = ..ChildrenGetStored(id)
    set ptr=0
    set separator=0
    while $listnext(ids,ptr,value) {
        set value = $lg(value)
        set:separator out = out _ ","

        set out = out _  "{"
        set out = out _  $$$ZENJSONPAIR("Name",##class(Example.Child).NameGetStored(value),"") _","
        set out = out _  $$$ZENJSONPAIR("Description",##class(Example.Child).DescriptionGetStored(value),"")
        set out = out _  "}"
        set separator = 1
    }
    
    set out = out _  "]"
    
    quit out
}