Robert Cemper · Apr 4, 2020 go to post

If I understand you correct you expect something  like

INSERT INTO new.MESSAGE (SELECT * from  EnsLib.HL7.Message  where id = ? )

this may work for rather modest designed relational tables but I doubt it will work for some complex structure as EnsLib.HL7.Message .

Subclassing is not the way to solve your problem for 2 reasons:

  • A subclass has always to match the .IsA() class type of its parent   
    (e.g. Employee as subclass of Person. Employee is also always a Person)
  • SubClasses share the storage with its parent.
    There are dirty tricks to avoid this but I assume you do not intend to change  
    EnsLib.HL7.Message.

There are ways to do something like this if you fiddle around in the storage structures. 
BUT: for reasons of transparency, documentation, and maintainability
I'd strongly recommend to use DTL. 

Fiddling around with COS in Ensemble is a rather tricky exercise.
Based on practical experience I can confirm that your successors will never forget you.

Robert Cemper · Apr 1, 2020 go to post

Ok It works in IRIS 2020.1    (e.g against /csp/samples/Web.SocketTest.cls)

The attempt of a backport failed for IRIS 2019.1 and Cache2018.1.3
There seem to be more serious changes than just the client code itself.

Robert Cemper · Mar 30, 2020 go to post

I started with %Stream.GlobalBinary, ... wondering what the problem might be.

Thinking over ENSEMBLE I moved to %GlobalBinaryStream

Robert Cemper · Mar 30, 2020 go to post

Hi Jenna,

I took some time to verify my suspicion.  (Caché 18.1)

You depend on the type of stream that is used in your object

#A)  %Library.GlobalBinaryStream or %Library.GlobalCharacterStream

  • if you have no stream yet you run do obj.MyStream.Write("whatever")
    then your stream will land in ^SSA.DocumentCacheS as expected
  • but if you get an already existing external stream and set obj.MyStream = myStreamOrefthen just the oref / OID of the stream is set including ^CacheStream.

Which seems to be your case   sadcrying​​​​​​​  angry
it's not a big surprise as ENSEMBLE may still use the old style. 

#B) using %Stream.GlobalBinary, ...

  • Both cases ended as expected with the stream in ^SSA.DocumentCacheS
    It seems to me that a CopyFromStream happens during the assignment.
    I'd name it expected behavior.   smiley
Robert Cemper · Mar 30, 2020 go to post

Not as string.
Parameters are stored as sub-object with the class object in  %Dictionary.* classes.
And serve as Information for the code to be compiled.

Robert Cemper · Mar 30, 2020 go to post

PARAMETER and DISPLAYLIST are both compiler directives and you can't mix them.

But you may workaround it by writing your own pair of DisplayToLogical /  LogicalToDisplay ClassMethods for this property´.


Parameter Active = 1;
Parameter Inactive =2;
Parameter Production = 3;
Parameter Upkeep 4;
/// DISPLAYLIST = ", Active, Inactive, Production, Upkeep",
Property StatusAs %String(VALUELIST = ",1,2,3,4") [ Required ];
ClassMethod StatusDisplayToLogical(%val) As %String
{ Quit $case(%val,..#Active:1,..#Inactive:2,..#Production:3,..#Upkeep:4,:""}
ClassMethod StatusLogicalToDisplay(%val) As %String
Quit $case(%val,1:..#Active,2:..#Inactive,3:..#Production,4:..#Upkeep,:""}

 
Robert Cemper · Mar 29, 2020 go to post

@Julius Kavay is fully correct.

The compiler was first written ~10 years before the idea of LLVM started  @ University of  Illinois.
Various interfaces allow your development very close to the data store. 

I'd suggest you contact your Sales Engineer @ InterSystems (Darmstadt ?) for disclosure of internals. 
 

Robert Cemper · Mar 27, 2020 go to post

it is an IRIS export

<?xml version="1.0" encoding="UTF-8"?>

<Export generator="IRIS" version="26" zv="IRIS for Windows (x86-64) 2019.1.1 (Build 609U)" ts="2020-03-22 18:56:51">

 

while for Cache it ooks like this:

<?xml version="1.0" encoding="UTF-8"?>
<Export generator="Cache" version="25">

 

it might be sufficient to change 26 to 25 to make your Caché happy

Robert Cemper · Mar 27, 2020 go to post

You don't have a great chance, but you may dig it down like this

And I assume once seen you get your display faster than this cycles where I had no idea on the subscript structure before

Robert Cemper · Mar 27, 2020 go to post

I don't know of reverse  order

BUT if you have some idea of the last subscript you may enter the starting  subscript.

instead of seeing the whole Global ^CONFIG

just one specific  subscript ^CONFIG("Telnet"

os starting from a specific subscript ^CONFIG("Telnet":

or from:to subscript ^CONFIG("ECP":"Journal"

or just the select subscript level with a closing bracket ^CONFIG("ECP":"Journal")

Basically it is the same behavior  of the ancient (not to say antique) routine ^%G

When it was written traversing a Global in reverse order was not implemented in Caché nor ist'S predecessors.
So no reverse display

It has a help function that tells you it's capabilities  DO HELP^%G

The %G utility displays global nodes. A "?" at the "Global ^" prompt
displays the global directory.
If you enter just the name of a global,
%G displays the entire global. You may also display a portion of the
global at different subscript levels or specific nodes.
 
A complete global reference, such as ^GLO(3,"BED",5) will display
only that particular node. You may specify a subtree, such as
^GLO(3,"BED", to display all descendants of that node. To display
both the node and its descendants, do not end your entry with a
comma or a right parenthesis.
 
You can leave a subscript field empty when you specify the subtree and
the %G utility displays any nodes matching the other subscripts:
^GLO(,"BED") will match any nodes with 'BED' as the second subscript.

 
You can specify a range of subscripts for a particular subscript
level by inserting a colon between the first and last subscript in the
range: ^PT(1,"ACC":"BIRTH"
 

You can use variables and simple expressions in a subscript
specification by assigning a value to the variable before calling %G.
For example SET ID=214 and enter something like ^PT(ID,0).

 
Robert Cemper · Mar 27, 2020 go to post

just use a single liner from terminal for the last 10 lines  or any number you need

s g="^myGlobal("""")" f i=1:1:10  s g=$q(@g,-1,%) q:g=""  w !,g zw %
Robert Cemper · Mar 26, 2020 go to post

Hi Jenna,

my personal experience with binary over HTTP is painful.

I'd suggest using Base64-Encoding (which means ASCII readable Characters only)
The downside is you have to decode it at the receiver side.
But that way it should be foolproof over across all proxy-, web- and other servers in between. 
HTTP was invented when there was EBCDIC for 8 bit and ASCII for 7 bit.  And some transport software hasn't improved since. sad 
 

Robert Cemper · Mar 22, 2020 go to post

why not use a free local mail server for testing?
I personally use the german speaking Hamster. But there are lots of them. Google is your friend

Robert Cemper · Feb 28, 2020 go to post

error -400 means there is an internal error

It might be caused by using object properties as  :context.anyname inside embedded SQL

give it a try and use "simple variables"  as :%myanyname , :%myShipmentTrackingNo 
and fill the context object outside the embedded SQL
as you do with SQLCODE

Robert Cemper · Feb 26, 2020 go to post

I'm surprised you don't see the obvious performance difference of looking for something of distinct length at the beginning of a string
vs. scanning an eventual rather long string for some bytes somewhere eventually including also composed strings as %AB%CD%.

keep in mind: Caché is built for speed, not for the comfort of the average programmer 

Robert Cemper · Feb 24, 2020 go to post

%STARTSWITH relates better to Caché internal structures and is faster in larger scale