go to post Vitaliy Serdtsev · Mar 14, 2019 Let's try to guess the return value of method t1(). Is that supposed to be hard? I immediately visually determined the result 20. To be honest I don't really understand the point which the author wanted to convey. Maybe it's the lack of English. In this case, the t3 method code is equivalent to the following code: ClassMethod t3(ByRef pA, ByRef pB) [ ProcedureBlock = 1 ] { set pA=4, pB=5 set x=$increment(pA)*$increment(pB) }PS: by the way, absolutely nothing will change fundamentally if you replace "return" with "quit" (and "ByRef" with "Output").
go to post Vitaliy Serdtsev · Mar 12, 2019 Hi Ponnumani. I would like to make a number of clarifications: VALUELIST = "A A- B B- O" -> VALUELIST = " A A- B B- O" it is necessary to consider the order of the fields in the global on the basis of Storage. For example, I have following Storage: <Data name="samplexlsconversionDefaultData"> <Value name="1"> <Value>%%CLASSNAME</Value> </Value> <Value name="2"> <Value>name</Value> </Value> <Value name="3"> <Value>DOB</Value> </Value> <Value name="4"> <Value>address</Value> </Value> <Value name="5"> <Value>PhoneNumber</Value> </Value> <Value name="6"> <Value>BloodGroup</Value> </Value> </Data> need to add check for the presence of double quotes in strings, e.g. bla"bla the date format for CSV should not be in the internal Caché format, because the date 37893 to users of other system/DBMS nothing says unlike e.g. 1944-09-30. I still prefer to use built-in tools when they are there, rather than reinventing the wheel. Class User.samplexlsconversion Extends (%Persistent, %Populate) { Property name As %String; Property DOB As %Date; Property address As %String; Property PhoneNumber As %Numeric; Property BloodGroup As %String(VALUELIST = " A A- B B- O"); ClassMethod TestExport2CSV() { d ..%KillExtent() d ..Populate(1000) s tmp=..%OpenId(1) s tmp.name=tmp.name_$c(34) d tmp.%Save() s tmp=..%OpenId(2) s tmp.name=$c(34)_tmp.name_$c(34) d tmp.%Save() s mgr = ##class(%SQL.Export.Mgr).%New() s mgr.FileName = "c:\Temp\test.csv" s mgr.ClassName = ..%ClassName(1) s mgr.TableName = $$$CLASSsqltablename($$$gWRK,mgr.ClassName) s mgr.Delimiter = "," s mgr.StringQuote = $c(34) s mgr.DateFormat = 3 s mgr.TimeFormat = 1 s mgr.TimeStampFormat = 1 s mgr.NoCheck = $$$YES s mgr.HasHeaders = $$$YES s cols="Name:S;Address:S;PhoneNumber:N;BloodGroup:S;DOB:D" f i=1:1:$l(cols,";") { s c=$p(cols,";",i) d mgr.ColumnNames.Insert($p(c,":",1)) d mgr.ColumnTypes.Insert($p(c,":",2)) } d mgr.Export() } }
go to post Vitaliy Serdtsev · Mar 11, 2019 Hi Robert. Exactly. Programmatically Managing Roles: This command can only be invoked either from a routine that is part of the CACHESYS database or if the current privileges held include Write permission for the CACHESYS database (%DB_CACHESYS:W). Note that setting $ROLES only alters a process’s added roles, not its login roles. There is a third way, but I specifically did not publish it.
go to post Vitaliy Serdtsev · Mar 11, 2019 Below are two ways without additional permissions on %DB_CACHESYS: #include %systemInclude n try{ s sslName="Test" w "1) GetSSLConfigList^%SYS.SECURITY1(.SSLConfigs)",!! w $$Test1(sslName) w !!,"2) $$ListSSLConfigs^%SYS.SECURITY(Client/Server)",!! w $$Test2(sslName) }catch(ex){ w "Error ", ex.DisplayString(),! } Test1(ssl) { d GetSSLConfigList^%SYS.SECURITY1(.SSLConfigs) f i=1:1:SSLConfigs return:SSLConfigs(i)=ssl $$$YES q $$$NO } Test2(ssl) { q ''$lf($lfs($$ListSSLConfigs^%SYS.SECURITY("Client")_","_ $$ListSSLConfigs^%SYS.SECURITY("Server")) ,ssl) }
go to post Vitaliy Serdtsev · Mar 6, 2019 And if so? CREATE TABLE test ( identifier VARCHAR(200) NOT NULL, value INTEGER COMPUTEONCHANGE("%%UPDATE") COMPUTECODE {&sql(select max(value)+1 into :{*} from test where identifier=:{identifier})}, PRIMARY KEY (identifier) )
go to post Vitaliy Serdtsev · Feb 28, 2019 SQL Projection of Object-Valued Properties INSERT INTO Package_Tables.Person_Address (Person, element_key, Address_AddressType, Address_StreetAddress) VALUES (1,2,1,'72 Fake Street')
go to post Vitaliy Serdtsev · Feb 28, 2019 Working example: Class dc.test [ Abstract ] { /// d ##class(dc.test).Test1() ClassMethod Test1() [ ProcedureBlock = 0 ] { new active,reactive,info,i kill info set active = 1 set reactive = 2 for i="active","reactive" { set info(i)= @i } zw info } /// d ##class(dc.test).Test2() ClassMethod Test2() [ PublicList = (active, reactive) ] { new active, reactive kill info set active = 1 set reactive = 2 for i="active","reactive" { set info(i)= @i } zw info } }
go to post Vitaliy Serdtsev · Feb 22, 2019 What will the following code output? s resptext="{""access_token"":""4SDFDSFDSF-aSDASDASD"",""expires_in"":""3300"",""refresh_token"":"""",""scope"":""sms_send"",""token_type"":""Bearer""}" s sc = ##class(%ZEN.Auxiliary.jsonProvider).%ParseJSON(resptext,,.pObject,1) i $$$ISOK(sc) { w pObject,!!, pObject."access_token",!, pObject."expires_in",! k arr s arr="" d pObject.%CopyToArray(.arr) zw arr }else{ d $system.OBJ.DisplayError(sc) }My result (2018.1): USER>d ^test 1@%ZEN.proxyObject 4SDFDSFDSF-aSDASDASD 3300 arr("access_token")="4SDFDSFDSF-aSDASDASD" arr("expires_in")=3300 arr("refresh_token")="" arr("scope")="sms_send" arr("token_type")="Bearer"
go to post Vitaliy Serdtsev · Feb 22, 2019 What will the following code output? USER>k arr d pObject.%CopyToArray(.arr) zw arrPS: "in" ≠ "expires_in"
go to post Vitaliy Serdtsev · Feb 18, 2019 Hi Adrian. Made a small example: #dim rs As %ResultSet s pid=4652 s rs=##class(%ResultSet).%New("%SYS.ProcessQuery:VariableByPid") f filter="","a*" { w !,"Filter = ",$$$quote(filter),! d rs.Execute(pid,,,,filter) while rs.Next() { w "Name = ",rs.Get("Name"),", Value = ",rs.Get("Value"),! } }Result: USER:4652>s a="11",b="22",a1="33" w $job 4652 USER:1392>w $job,! d ^dc 1392 Filter = "" Name = a, Value = 11 Name = a1, Value = 33 Name = b, Value = 22 Filter = "a*" Name = a, Value = 11 Name = a1, Value = 33
go to post Vitaliy Serdtsev · Feb 16, 2019 The presence of a potential opportunity to read the documentation via "Class Reference". For macros from *.inc this is not possible.
go to post Vitaliy Serdtsev · Feb 15, 2019 Using Dynamic SQL Dynamic SQL Using Older Result Set Classes
go to post Vitaliy Serdtsev · Feb 15, 2019 See: %SYS.LockQuery %SYS.ProcessQuery:VariableByPid()/VariableByJobNumber() %SYSTEM.Memory:VariableStats() PS: $SYSTEM.Util.CleanDeadJobs().
go to post Vitaliy Serdtsev · Feb 14, 2019 Still another option: Class dc.test Extends %Persistent { Property JSONData As list Of %String [ SqlListType = SUBNODE ]; ClassMethod Test() { d ..%KillExtent() f l=$lb("apple","pear","plum"),$lb({"Name":"Kyle"}.%ToJSON(),{"Name":"Evgeny"}.%ToJSON()) { s t=..%New() d t.JSONData.InsertList(l) d t.%Save() } zw @$system.Dictionary.comMemberKeyGet($this,$$$cCLASSstorage,$$$nameDefaultStorageNameGet,$$$cSDEFdatalocation) s rs=##class(%SQL.Statement).%ExecDirect(,"select distinct json_arrayagg(JSONData %foreach(test)) from dc.test_JSONData") while rs.%Next() { s jsonStr=rs.%GetData(1), json=[].%FromJSON(jsonStr) w !,jsonStr,", %Size()=",json.%Size(),! } } }Result: USER>d ##class(dc.test).Test() ^dc.testD=2 ^dc.testD(1)=$lb("") ^dc.testD(1,"JSONData")=3 ^dc.testD(1,"JSONData",1)="apple" ^dc.testD(1,"JSONData",2)="pear" ^dc.testD(1,"JSONData",3)="plum" ^dc.testD(2)=$lb("") ^dc.testD(2,"JSONData")=2 ^dc.testD(2,"JSONData",1)="{""Name"":""Kyle""}" ^dc.testD(2,"JSONData",2)="{""Name"":""Evgeny""}" ["apple","pear","plum"], %Size()=3 [{"Name":"Kyle"},{"Name":"Evgeny"}], %Size()=2Doc: SqlListType JSON_ARRAYAGG
go to post Vitaliy Serdtsev · Jan 16, 2019 if I call giveMeAFalseMe from Cache when it's returning "true" or "false", Cache will translate "true" into a truthy %Boolean return value, right? No, it does zenBool, which is on the client side. The important thing is that #server()# always returns a string, for example: <script language="cache" method="giveMeAFalse" arguments="" procedureblock='1' returntype="%Integer">return 4</script> var bool = #server(..giveMeAFalse())#; console.log("bool = " + bool); console.log("typeof bool = ", typeof bool); Result: bool = 4 typeof bool = string PS: you can further explore the sources of the #server()# -> cspHttpServerMethod() -> cspProcessResponse(), which are in the file cspxmlhttp.js.
go to post Vitaliy Serdtsev · Jan 15, 2019 See zenConvertType() [///Converts a typed value returned from the server to an appropriate JS type] from zenutils.js. Try this: <script src="zenutils.js"></script> <script language="javascript"> function isItActuallyFalse() { var bool = zenConvertType('BOOLEAN',#server(..giveMeAFalse())#); ... } </script> <script language="cache" method="giveMeAFalse" arguments="" returntype="%Boolean" procedureblock='1'>return $$$NO</script>or var bool = zenBool(#server(..giveMeAFalse())#); ... <script language="cache" method="giveMeAFalse" arguments="" returntype="%Boolean" procedureblock='1'>return "false"</script>
go to post Vitaliy Serdtsev · Dec 31, 2018 s tags=$lb("a","b","c"), str="c,a1,d,b,f" s l=$lfs(str),ptr=0 while $listnext(tags,ptr,tag) { w:$lf(l,tag) tag,! }Result b c