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

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
}

The easiest way would be to configure web server on customersdomain.com to act as a reverse proxy. In this case it would proxy requests to yourownserver.com or wherever you need.

Another way is to install CSP Gateway on a customersdomain.com. After that connect CSP Gateway to your Cache/Ensemble/InterSystems IRIS instance on yourownserver.com. And connect web server on customersdomain.com to CSP Gateway on customersdomain.com.

Advantage of this approach is that static would be served directly from customersdomain.com server.

You can try to write to a TCP device with SSL. Doesn't require additional permissions:

ClassMethod Exists(ssl As %String) As %Boolean
{
	#dim exists As %Boolean = $$$YES
	set host = "google.com"
	set port = 443
	set timeout = 1
	
	set io = $io
	
	set device = "|TCP|" _ ##class(%PopulateUtils).Integer(5000, 10000)
	try {
		open device:(host:port:/SSL=ssl):timeout	
		use device
		
		// real check
		write "GET /" _ $c(10),*-3
		// real check - end
		
		// should be HTTP/1.0 200 OK but we don't really care
		//read response:timeout
		//write response
	} catch ex {
		set exists = $$$NO
	}
	
	use io
	
	close device
	
	
	quit exists
}

It's slower than direct global check but if you want to do it rarely,  I think it could be okay. Doesn't require additional permissions.

Code to compare times:


ClassMethod ExistGlobal(ssl) [ CodeMode = expression ]
{
$d(^|"%SYS"|SYS("Security","SSLConfigsD",ssl))#10
}

/// do ##class().Compare()
ClassMethod Compare(count = 1, ssl = "GitHub")
{
    Write "Iterations: ", count,!
    Write "Config exists: ", ..Exists(ssl),!

    set start = $zh
    for i=1:1:count {
        set exists = ..Exists(ssl)
    }
    
    set end = $zh
    
    set time = end - start
    Write "Device check: ", time,!
    
    set start = $zh
    for i=1:1:count {
        set exists = ..ExistGlobal(ssl)
    }
    
    set end = $zh
    
    set time2 = end - start
    write "Global check: ", time2,!
}

Results:

Iterations: 1
Config exists: 1
Device check: .054983
Global check: .000032

Iterations: 1
Config exists: 0
Device check: .017351
Global check: .00001

Iterations: 50
Config exists: 1
Device check: 2.804497
Global check: .000097

Iterations: 50
Config exists: 0
Device check: .906424
Global check: .000078

I can use ($ztimestamp) to get UTC time and then convert it into local time i am using the below way is this correct?

 SET stamp=$ZTIMESTAMP
w !,stamp
SET localutc=$ZDATETIMEH(stamp,-3)
w $ZDATETIME(localutc,3,1,2)

Yes, sure.

My Question is how i can program this task in the below way

You heed to add three hours.  Use DATEADD method for this:

write $SYSTEM.SQL.DATEADD("hour", 3, yourDate)

The code looks good. What error are you getting?

Try replacing stream2 %Stream.FileCharacter with %Stream.FileBinary.

Try replacing stream1 %Stream.FileCharacter with %Stream.TmpBinary.

If you have message sample less than 3,5 mb in size try to write a test without intermediate stream.

You probably should write to a pdf file and not a txt one.

If you can, get a sample original/decoded file. Compare original file and your stream2 file using hex editor to spot differences.

I' do it in 2 steps.

  1. Iterate over data array and build a temp local structure to hold all additional items you need
  2. Iterate over this new structure and add these items to data array.

You can add to array using %Push method:

do Obj.data.%Push(newItem)

If you want to push at a specific posiiton, use %Set

do Obj.data.%Set(position, newItem)

That said your later structure contains data which does not exist in the original structure (text values for projects and sub-projects) so you need to get it from somewhere.

Also is project - subproject hierarchy one-level, or there could be an arbitrary number of sub-project levels (i.e. 10  10-1 → 10-1-1 → 10-1-1-1)?

Some ideas.

1. The problem is isc.rabbitmq.API  class was imported with an error. Delete this class and try this code (post output):

Set class = "isc.rabbitmq.API"
Set classPath = ##class(%ListOfDataTypes).%New()
Do classPath.Insert(PATH-TO-JAR)
Set gateway = ##class(%Net.Remote.Gateway).%New() 
Set sc = gateway.%Connect("localhost", PORT, $Namespace, 2, classPath)
Zwrite sc
Set sc = gateway.%Import(class)
Zwrite sc
Write ##class(%Dictionary.CompiledClass).%ExistsId(class)

2. Try recompiling isc.rabbitmq.API  class.

3. Maybe have 2 amqp jars with com.rabbitmq.tools.jsonrpc.JsonRpcException class.  The only class you should import is isc.rabbitmq.API  class. It shouldn't pull many additional ones.

4. What version of AMQP are you using? I'm using amqp-5.0.0. Try the same verison?

I suppose you can solve this problem by separating your persistent class into abstract definition and persistent "storage only" class.

It could look like this:

Class test.Abstract.Order [ Abstract ]

{

Property a;

Method doStuff()

{

}

}

and persistent class:

Class test.Order Extends (test.Abstract.Order, %Persistent)

{

/*Generated Storage */

}

And only map test.Abstract package. This way you'll need to:

  • Copy test.Order class manually (but only once, as it does not change).
  • Recompile test.Order class in each namespace if Abstract realization changes.

But in this setup persistent class could be tuned, etc.. Also you can automate deployment steps with CI/CD tools.

You get this error (Datatype value '2019-02-01' is not a valid number) because %Date stores data in horolog format, so you need to do one of:

  • (Recommended approach) Convert date value from external format (2019-02-01) into internal format (horolog) using $zdh function:
Set consumerRecord.ActivePeriod.StartDate = $zdh(obj.activePeriod.startDate, 3)
  • Use datatype for which this value is valid, i.e. %TimeStamp. To check, all datatype classes offer IsValid method, you can use it to check value validity
zw ##class(%TimeStamp).IsValid("2019-02-01")
  • If you're using InterSystems IRIS you can store dates as %PosixTime.

Regarding Atelier, I use it to debug REST services and it shows variable values. You can try to reinstall it. If you're on Windows you can also use Studio.