Robert Cemper · Nov 9, 2018 go to post

I oppose:

- all text coloring, fonts sizes help to express the importance of text. 

- text from right to left  is only useful for Hebrew or Arabic writing:  not my world

- special characters help a lot if you don't have them on your keyboard   ¿isn't it ? my 2 ¢

-  what's bad with smileys?  crying

I do spell checking with Grammarly. the embedded only confused me.

Source could need an improvement to wrap the text in the window. The single line display is cumbersome.

Robert Cemper · Nov 5, 2018 go to post

To separate physical storage from applications you may do this inside Caché using ECP 

Robert Cemper · Nov 5, 2018 go to post

As stated in the 2nd paragraph:

Unlike the standard .NET binding, the eXTreme APIs do not use TCP/IP to communicate with Caché.
Instead, they use a fast
in-memory connection

So by definition, it can't be on a different server. It acts like COS but in the .NET based language of your choice.
 

Robert Cemper · Nov 4, 2018 go to post

Still another approach using your original "solution" in PHP following the idea of a Micro-Service.

Instead of a mimic of what PHP might do I use it directly for this purpose.
That way more sophisticated functionalities that can be used without recoding.

I extended your test to include doubled double quotes

USER>write  %dstr
ABC Company,"123 Main St, Ste 102","Anytown, DC",10001,234-567-8901,"hi ""rcc"" was here"
USER>set reply=$$^phpCSV(%dstr) write reply,!! zwrite reply
ABC Company       123 Main St, Ste 102    Anytown, DC 10001   234-567-8901    hi "
rcc" was here
 
reply="ABC Company"_$c(9)_"123 Main St, Ste 102"_$c(9)_"Anytown, DC"_$c(9)_"10001"_$c(9)_"234-567-8901"_$c(9)_"hi ""rcc"" was here"

*

and here the code:

phpCSV(str) {       ; use PHP for conversion
#define php "............\php.exe "    ; add location of php.exe
#define pipe "|CPIPE|1"
  set file="myTest.php"
  open file:"WN" use file
  write "<?php "
        ,!,"$str='"_str_"';"
        ,!,"$strtotab = implode('\t', str_getcsv($str, ','));"
        ,!,"print_r($strtotab);"
        ,!,"?>",!
  close file
  open $$$pipe:$$$php_file
  use $$$pipe read result
  close $$$pipe
  use 0 ; write result
  quit $replace(result,"\t",$c(9))
}
Robert Cemper · Nov 2, 2018 go to post

GREAT ! 
all well-documented code!
no (dirty) Harry_Potter_Coding !

I was sure you know it

Robert Cemper · Nov 1, 2018 go to post

The Unix/Linux world often uses LF := $C(10) as line terminator
while in Win (and VMS) world  CRLF := $C(C13,10) is a default.
 So you depend on the source system providing the data.

Suggested approach: use LF as the (common) line terminator  and   just drop $C(13) or   &#x0D; from your input record by

$replace($translate(record,$c(13)),"&#x0D;","")

Before any other processing.

Robert Cemper · Nov 1, 2018 go to post

OK, this handles double quotes. But only INSIDE a quoted string

parseCSV(string,newsep,sep=",",quote="""",newquote) {    ;adjust for flexible quoting
    set res="",newsep=$g(newsep,$c(9)),newquote=$g(newquote,quote)
    for  {
        if $g(string)[sep 
            if $e(string)=quote {
                set string=$replace(string,"""""",$c(2)) ; exclude double quotes
                set part=$P(string,quote,2)
                    ,string=$replace($p(string,part_quote_sep,2,*),$c(2),"""""")
                    ,res=res_newquote_$replace(part,$c(2),"""""")_newquote_newsep }
            else  
                set part=$P(string,sep),string=$p(string,sep,2,*)
                    ,res=res_part_newsep 
        else  
               set res=res_$g(string) quit }
        }
    quit res

}

-

HTH 

Robert Cemper · Nov 1, 2018 go to post

you are right. I didn't think on empty parts and doubled double quotes yes
which I never met from CSV.
next level exercise wink 

Robert Cemper · Nov 1, 2018 go to post

I discourage since years the use of $ZU(...) functions as they aren't documented since 2010. 
I recently had to dig back to 2009 for just a weak hint what might happen.

It is even worse with all the internal stuff around %occ* and similar.
No docs. No guaranty of the life cycle. No (external) notice of eventual changes. Mostly as a deployed code.

If it is used inside a $system.* or part of a generated code that's OK. The responsibility is not at the user side.

Verifying those "specials" with every release change can be a very heavy exercise. 
(just experiencing this on a system locked down to on an older version unable to migrate)

Robert Cemper · Nov 1, 2018 go to post

not being verbose in %occ* world I had this solution also allowing to change quoting
 

parseCSV(string,newsep,sep=",",quote="""",newquote) {    ;adjust for flexible quoting
  set res="",newsep=$g(newsep,$c(9)),newquote=$g(newquote,quote)
  for  
     if $g(string)[sep 
       if $e(string)=quote {
          set part=$P(string,quote,2),string=$p(string,part_quote_sep,2,*)
                ,res=res_newquote_part_newquote_newsep }
     else  
         
set part=$P(string,sep),string=$p(string,sep,2,*)
               ,res=res_part_newsep 
    else  
          set res=res_$g(string) quit }
     }
  quit res
}

BTW.
It's an excellent test exercise for new COS programmers
I'll add it to my collection.

Thanks   yes
 

Robert Cemper · Oct 29, 2018 go to post

Congratulations!  yesyesyes
In past, we had a similar event in Austria named "Tech Talk"  that formed a national user community over time.

I wish you a lot of success,
Robert

Robert Cemper · Oct 21, 2018 go to post

OK.  for some reason the most important part of the link was truncated.

https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25CSP.BinaryStream

I hope it doesn't hide again.

The basic mistake happens here the definition of Request 
https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25CSP.Request

And you are right. %CSP.Stream has no Read method because  ContentType tells you the true object . 
As in the example:

It could have been %CSP.CharacterStream as well.

Both extend over some steps %GlobalStreamAdaptor which have all the READ, WRITE, ....methods

Just reading docs and not checking inherited methods (e.g. in Studio) is mostly misleading.

Robert Cemper · Oct 18, 2018 go to post

Just adding CACHESYS to mirror could be a deadly exercise

Who then is primary? Me or my Mirror?

But to achieve your goal you may have an additional DB. Let's name it SYSMIRROR
And now you use global / subscript level mapping to place the common information there.
e.g. ^SYS("Security") or parts of it ("RolesD","UsersD", ..)  whatever you think you need.
I never tried it but it could not see a contradiction.

For better synchronization and uniqueness, I'd personally prefer to have this SYSMIRROR accessed over ECP while holding a local copy of SYSMIRROR for backup /  failover

Robert Cemper · Oct 17, 2018 go to post

YES it is possible.

- see your sub_query first working 
- just custom_view seems to miss the typical dot in table and view names 

Views are just a kind of shortcut to a query formula.

 in namespace SAMPLES you could do this

select Home_City, DOB, name,
(select Name from sample.personview sub where sub.DOB=main.DOB ) SubName
 from Sample.Person main

The example doesn't make much sense but it shows that this works

Anyhow, why don't you just use a JOIN  like this?

select Home_City,main.DOB, main.name, sub.name
from Sample
.Person main
left outer join sample.personview sub on
sub.DOB=main.DOB

or in your case 

select    MsgId,   FileName, ReportName
from main_table LEFT OUTER JOIN   custom_view
ON     MsgId = ReportId

Again: both table name and view name look odd to me
 

Robert Cemper · Oct 17, 2018 go to post

Hi Sean,
somewhat likely, using indirection instead of eXecute wink

 set %ref="obj."_prop,key="" for  set key=$order(@%ref@(key),1,val) quit:key=""  write key,?5,val,! 

Robert Cemper · Oct 17, 2018 go to post

USER>s x="&#1050;&#1077;&#1088;&#1080;&#1084;&#1073;&#1072;&#1081; &#1053;&#1091;&#1088;&#1080;&#1103;"

USER> w ##class(%CSP.Page).UnescapeHTML(x)
Керимбай Нурия

Robert Cemper · Oct 12, 2018 go to post

It would be useful to have a wider context of your problem.  
 invalid OREF may have many reasons and it's not obvious how this relates to your initial problem

Robert Cemper · Oct 11, 2018 go to post

if you do it in object Script you just missed the concatenation operators (Underscore) _ 

""""_tect_"""" 

Robert Cemper · Oct 11, 2018 go to post

In SQL you do SELECT '"'||field||'"' ....

String delimiter in SQL are  single quotes '   String concatenator is ||   Double pipe

Robert Cemper · Oct 11, 2018 go to post

Brendan,

I share your concerns. The initial request didn't mention Fileman at all.
This is just a hint how a construct like this could be opened to SQL access. 
I've seen so many old MUMPS code that would have never taken its way to objects without.
It#s clear that this requires wise use and careful handling.
 

Robert Cemper · Oct 10, 2018 go to post

for pure object access, you have a getter and a setter method.  no magic

if also want to use it for SQL
- you need SqlComputed code. This will also replace your (object)Getter.

- to set your local variable also by INSERT or UPDATE you need to add  UPDATE and INSERT Trigger code.

example;

Class DC.Setter Extends %Persistent [ Not ProcedureBlock ]
{
Property DUZ As %String [ Calculated, SqlComputed, SqlColumnNumber = 2
,
       SqlComputeCode = {set {*} = DUZ(2)}  ];
// for settig object property
Method DUZSet(Arg As %String) As %Status [ ServerOnly = 1 ]
 set DUZ(2)=Arg  Quit $$$OK   }
Trigger UpdTrigger [ Event = UPDATE ]
{ set DUZ(2)
= %d(2) ,%ok=1 }
Trigger InsTrigger [ Event = INSERT ]
set DUZ(2)=
  %d(2) ,%ok=1 }

--

To anticipate critics:
Some people may say it's dirty coding.  YES !! But it works.