Robert Cemper · Apr 16, 2018 go to post

#1) check that there exists a valid class WINSURGE*...   

#2) in Mgmt Portal > System Explorer > SQL you should see as Table WINSURGE_DMP.WINSURGE_RESULT_FACT

#3) #SQLCompile Path=cancreg 
seems the real source of your problem as it sets a default package 
cancreg  wherever that may come from

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lbSQLCompile_Path

Eliminate it as your table is already full qualified  WINSURGE_DMP.WINSURGE_RESULT_FACT

In addition :  - VALUES :FIELD()
do you really write to ALL fields of the external table ??? 

Hint:

try to execute your SQL statement first from Mgmt Portal using dummy values before coding with strange macros directives

start with a simple statement to see if the connection works as expected:

SELECT COUNT(*) FROM WINSURGE_DMP.WINSURGE_RESULT_FACT

then try:

INSERT INTO WINSURGE_DMP.WINSURGE_RESULT_FACT VALUES (1,2,3,4,5,6)   -- whatever it needs

Robert Cemper · Apr 16, 2018 go to post

I like that !  yes

BUT: as in the original request I seem to miss the file.Read()  to fill Line somewhere in the loop.  wink

Robert Cemper · Apr 16, 2018 go to post

Enable long strings in System Mgmt Portal and get strings up to 3.4 MB

System > Configuration > Memory and Startup​

 ​

Robert Cemper · Apr 16, 2018 go to post

Time in Posix is the time as %Integer counting from Jan 1st, 1970.  A UNIX definition.
dates before are negative integers (e.g. birthdate before 1970 wink )   
      [that was a reason to start $h with Jan 1st, 1840. The year the oldest veteran (in 1960)  from civil war at MGH was born ] 

Robert Cemper · Apr 16, 2018 go to post

the WRITE is just to visualize the example

the loop in YOUR class could be: 

 for msg=1:1 set msg(msg)=stream.ReadLine() quit:stream.AtEnd 


but that's just standard COS programming. Nothing special. see here
Then you have the local array msg with your SOAP message
Similiar the Try{ } Catch {}  construct that ignores the error that you experience as you don't get a real SOAP response here.

Robert Cemper · Apr 15, 2018 go to post

You may create a normal SOAP Client in Studio using the Wizard.

Then you add a transport class to display / dump your request. (example in SAMPLES)

Class SOAPDemo.Transport Extends %RegisteredObject
{
ClassMethod DoSOAPRequest(
 client As %SOAP.WebClient,
 Action As %String,
 OneWay As %Boolean = 0,
 stream As %FileBinaryStream,
 ByRef responseStream As %GlobalBinaryStream) As %Status
{

    write !,"**** SOAP Request Begin ****",!
    for  write stream.ReadLine(),! quit:stream.AtEnd
    write !,"**** SOAP Request End ****",!
    quit 
$$$OK
}
}

Example to use it :

SAMPLES>set soap=##class(SOAP.DemoProxy).%New()
 
SAMPLES>set soap.Transport=##class(SOAPDemo.Transport).%New()  ;; add cusomized transport
 
SAMPLES>try {write !,soap.Mission() } catch {}    ;; you don't get a reply, so ignore it
  
**** SOAP Request Begin ****
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'&gt;  
<SOAP-ENV:Body><Mission xmlns="http://tempuri.org"></Mission></SOAP-ENV:Body>
</SOAP-ENV:Envelope>

**** SOAP Request End ****
 
SAMPLES>try {write !,soap.AddInteger(17,4) } catch {}
 
**** SOAP Request Begin ****
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'&gt;  
<SOAP-ENV:Body><AddInteger xmlns="http://tempuri.org"><Arg1>17</Arg1><Arg2>4</Arg2></AddInteger></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
**** SOAP Request End ****

 

so you get Envelope + Body well separated

Robert Cemper · Apr 14, 2018 go to post

in technology space it's nice and compatible to the UNIX/LINUX world
in the commercial arena it is just an alien

Robert Cemper · Apr 13, 2018 go to post

%Date is just handling +$h, no time  (that would be %Time)
%Timestamp is the real object equivalent of $h
 

Robert Cemper · Apr 13, 2018 go to post

That makes it more clear, but not easier.

Class %SOAP.WebClient  is the base for any SOAP Client in Caché.
It has a property Transport to provide a registered class for alternate transport (or no immediate transport in your case)
check the code starting with Method InvokeClient(...
and look for transport within the next 50 lines to see how that works up to here

#; Make the request
Set sc=transport.DoSOAPRequest($this,Action,OneWay,stream,.responseStream)


Just to be clear:
I personally won't do it that way because of all the related maintenance risks.

Robert Cemper · Apr 13, 2018 go to post

If you don't do to detect the structure using TCPtrace or WireShark or similar you will not see it.

As I noted. It's an advice for hackers (and network engineers)

Robert Cemper · Apr 13, 2018 go to post

YES. and once you have identified the content you should be able to modify it in object script according to your needs with $REPLACE, $TRANSLATE, ...... as any other string

Robert Cemper · Apr 13, 2018 go to post

In order to use a table in an external DB you need to LINK this table to your Caché instance.
There's a Wizard in Mgmt Portal  System > SQL > Wizards > Link Table

It connects to your external table using  SQLgateway and creates a proxy class in your namespace
that presents the table with all SQLnames ...( underscores, ...) as if it was a local table but with a special external storage
Then you use this proxy class as you would do with a local one.
Table 'WINSURGE_RESULT_FACT' should then be visible and accessible. 

It might be somewhat slower than Globals  wink

Robert Cemper · Apr 13, 2018 go to post

Hacker's advice:
Create a SOAP client with Studio - Assist.
Send your request anywhere and hijack it with TCPtrace or WireShark or similar.
Now you have the string that you intend to modify and to send.

Anyhow, I'm somewhat surprised about the subject.

Robert Cemper · Apr 13, 2018 go to post

Mike,

please create a new question as the solution is not related to the previous one.

Thx.

Robert Cemper · Apr 11, 2018 go to post

Evgeny,
The type of mirror depends on how it should be used:

  • for Disaster Recovery, it is important to get as much real-time date across as possible.
    it is irrelevant to have indices, cubes or similar in your (very) remote data center. 
    so I'd recommend asynchronous Mirror / Shadow to feed it.
    What else you require can be generated from existing data. 
     
  • for High Availability, everything to continue / restart  should be available permanently
    so my recommendation is Synchronous Mirror
     
  • but in parallel, there is the recommendation to separate Production data from DeepSee cubes
    less for cube maintenance but fo queries. And that's really important!
     
  • As a consequence, you would need a secondary mirror to provide high availability + performance also
    for your DeepSee cubes. Which is not a waste of effort as it allows load balancing across DeepSee. 
     
  • In any case, it is a tricky exercise to build, verify and manage such a configuration.  
      
Robert Cemper · Apr 11, 2018 go to post

Typically a Message in Ensemble is inheriting from Ens.Request
e.g. Class EnsLib.Testing.Request Extends Ens.Request

I have no Healthshare at hands to identify your correct message
just to confirm 
Enslib.HL7.Message does NOT extend Ens.Request as it is a  Persistent object on it's own.

Robert Cemper · Apr 11, 2018 go to post

Your message might be locked by some other process at that time. 
Try to raise your Lock level to have exclusive access to your persistent object  %GetLock(id) which you need during %Save()
 If it fails you should find out who else is locking it. 

Robert Cemper · Apr 9, 2018 go to post

That's mine:

ClassMethod main(As %Integer = 10)
r=1:1:! c=1:1:$s(c=1!(r=1)!(r=s)!(c=s)!(c=r)!(s-r+1=c):"#",1:" ")}
Robert Cemper · Apr 9, 2018 go to post

Check if Output Frame is open.
IF it resists to appear.

  • goto fullscreen mode
  • click to View / Output  (ALT+2)

If still invisible:

  • move the mouse pointer slowly up from the down border to catch the top border of the output frame
  • pull it up to make is visible.

Robert Cemper · Apr 9, 2018 go to post
  • select target namespace (e.g. SAMPLES)
  • Find in files 
  • Find What:   (e.g. person)
  • file type (e.g. *.cls )
  • uncheck all boxes
  • forget all filters
  • eventually check  Search in System Items
  • (Match case is a source of surprises )
  • (Match whole word only is fair chance to see nothing)
  • FIND and be patient to see the full result

Robert Cemper · Apr 7, 2018 go to post

In Caché classes the general rule is to remove underscores for internal use.

For Properties you have the parameter SqlFieldName to keep the original name and also use it for SQL access. (e.g. INSERT)
 

Property AccessionDate As %Date [ SqlFieldName = ACCESSION_DATE ];
Robert Cemper · Apr 7, 2018 go to post

"  I found a utility in CACHE "   which one ?

most likely you might pass column names as string parameters "ACCESSION_DATE"

Robert Cemper · Apr 5, 2018 go to post

Sorry to be late. I was busy today:

Thanks to  @Eduard Lebedyuk

I did it in a traditional one-liner: 79  77 char.   + 4 char extra to read the size.
I'll wrap it into a method later to see how much waste of space this generates. devil

5 min. later:
OK. Method consumes 3 char. extra {} to enclose it + blank at the start   =>>> 82   80  ~3.9% overhead

s=1...4 looks odd but it improves.

f j=1:1:15 zw j d ##class(DC.size).main(j) 
j=1
#
j=2
##
##
j=3
###
###
###
j=4
####
####
####
####
j=5
#####
## ##
# # #
## ##
#####
j=6
######
##  ##
# ## #
# ## #
##  ##
######
j=7
#######
##   ##
# # # #
#  #  #
# # # #
##   ##
#######
j=8
########
##    ##
# #  # #
#  ##  #
#  ##  #
# #  # #
##    ##
########