go to post Vitaliy Serdtsev · Nov 13 A long time ago, back in the days of Caché, I made a series of articles on creating a web application based on REST and CSP with my own static file processing. Try it, maybe you can use something from there.
go to post Vitaliy Serdtsev · Nov 13 I will assume that you are using "Normal" (in which the user _SYSTEM is turned off) or even "Locked Down" (the user "UnknownUser" has no roles at all): Initial User Security SettingsDOC I'm using "Locked Down", IRIS 2025.2CE and ran into a lot of different bugs when using WebTerminal v4.9.5: <PROTECT>endSession+25^%SYS.cspServer <LICENSE LIMIT EXCEEDED> etc. Fortunately, the WebTerminal source code is available for analysis and editing. The problem can be solved in two ways: either fix the source code or add the missing role. I chose the latter. In my case, it is enough for the web application /terminalsocket to add the %Admin_Secure role in addition to the existing roles. After that, it doesn't hurt to clean up all existing sessions: kill ^WebTerminal("AuthUser")If the <LICENSE LIMIT EXCEEDED> error persists after this, restart the IRIS instance. PS: Advisory for IRISSECURITY in InterSystems IRIS 2025.2
go to post Vitaliy Serdtsev · Nov 13 Credentials are not requested, as most likely your existing session has not expired yet. By default, the timeout is 1 hour (see the "WebTerminal.Engine:WSKEYEXPIRES" class parameter).
go to post Vitaliy Serdtsev · Nov 5 I would venture to assume that this difference is due to the overhead of calling the class method. In other words: ##class(%DynamicArray).%New() -> ..%OnNew() -> $ZU() [] -> $ZU() There was a similar topic: Shared code execution speed
go to post Vitaliy Serdtsev · Oct 31 "Real life" *.inc entry is to execute macro routine "Entry^HS.Local.VA.Util.Log(%arr,,"D")" if Global ^GlFSL("Debug") is >0 by calling from a classmethod as $$$TestIf(arr) - no return value is required. #define TestIf(%arr) if (^GlFSL("Debug")>0) {do Entry^HS.Local.VA.Util.Log(%arr,,"D")} ;or #define TestIf(%arr) do:^GlFSL("Debug")>0 Entry^HS.Local.VA.Util.Log(%arr,,"D") Usage: $$$TestIf(5)
go to post Vitaliy Serdtsev · Oct 31 Statement "set a = $$$TestIf(3)" is included into a classmethod with no other code in. Expected output 5 What is the expected result for the next operator? set a = $$$TestIf(-3)
go to post Vitaliy Serdtsev · Oct 30 You have two mistakes. Instead for {i=1:1:%count set x=should be for i=1:1:%count {set x= Macros ≠ Function A working example: #define MyLoop(%count,%result) set ref="",%result="" for i=1:1:%count set ref=$order(^%SYS("JOURNAL",ref),-1),%result=%result_$listbuild(ref) $$$MyLoop(5,x) write $listtostring(x)
go to post Vitaliy Serdtsev · Oct 30 Example of @Robert Cemper compiles without errors for me (even on Caché 2018.xxx): Class dc.a [ Abstract ] { ClassMethod Test() { #define MyLoop(%count) set x="" for i=1:1:%count set x=$order(^%SYS("JOURNAL",x),-1) write x,! $$$MyLoop(5) } }
go to post Vitaliy Serdtsev · Oct 30 If the array is multidimensional, then you can't do without loops (the code is without error handling): #define ArrayToStr(%arr,%str) set ref=$name(%arr),%str="s " for {set ref=$query(@ref,1,val) quit:ref="" set %str=%str_$$FormatName^%qcr(ref,1)_"="_##class(%Utility).FormatString(val)_","} set $extract(%str,*)="" #define StrToArray(%str) xecute %str Usage: set a(0)=7 set a(1,"color")="green" set a(1,"color","green")="" set a("color",$listbuild($double(3)))=$listbuild("red","blue") $$$ArrayToStr(a,str) zwrite str kill a $$$StrToArray(str) zwrite a
go to post Vitaliy Serdtsev · Oct 30 I would like to have *inc file entry to convert an array into a string and string into an array. If the array is one-dimensional, then you can do without cycles altogether. I'll give you a small example below: #define Array1ToJSONString(%arr,%json)##continue s ##unique(new)=##class(%ZEN.proxyObject).%New()##continue d ##unique(old).%CopyFromArray(.%arr),##continue ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.%json,##unique(old))##continue s %json=%json.Read(3641144) #define JSONStringToArray1(%json,%arr)##continue d ##class(%ZEN.Auxiliary.altJSONProvider).%ConvertJSONToObject(%json,,.##unique(new)),##continue ##unique(old).%CopyToArray(.%arr)Usage: set a("color")=$listbuild("red","blue") set a("price")="expensive" set a("size")=$listbuild("large","small") $$$Array1ToJSONString(a,jsonStr) zwrite jsonStr $$$JSONStringToArray1(jsonStr,b) zwrite b
go to post Vitaliy Serdtsev · Oct 29 Attention: You can INCLUDE just 1 single *.INC in a class definition. Including Include Files To include multiple include files at the beginning of a class definition, the syntax is of the form: Include (MyMacros, YourMacros)
go to post Vitaliy Serdtsev · Aug 21 import iris # first, we connect to the %SYS namespace conn = iris.connect('localhost:1972/%SYS','_SYSTEM',pwd,10,True) irispy = iris.createIRIS(conn) # here we switch to the USER namespace newNameSpace = irispy.classMethodString('%SYSTEM.Process','SetNamespace','USER') # now we can call the method from the new namespace #print(irispy.classMethodInteger('DC.Unix','RoundPosixToSeconds',1154669852181849976)) conn.close()
go to post Vitaliy Serdtsev · Aug 15 #Include %sqlx set newposix = $$$sqlxPosixTimeEncode(+$p($$$sqlxPosixTimeDecode(posix),".",1))Сheck: for posix = 1154669852181849976, -6979664624441081856, 1406323805406846975 { set newposix = $$$sqlxPosixTimeEncode(+$p($$$sqlxPosixTimeDecode(posix),".",1)) write ##class(%PosixTime).LogicalToTimeStamp(posix),!, ##class(%PosixTime).LogicalToTimeStamp(newposix),!! } 2025-05-27 12:06:15.003 2025-05-27 12:06:15 0001-01-01 00:00:00 0001-01-01 00:00:00 9999-12-31 23:59:59.999999 9999-12-31 23:59:59
go to post Vitaliy Serdtsev · Aug 11 source code of dc.observation_lab Class dc.a Extends %Persistent [ SqlTableName = observation_lab ] { Index iCode On code; Index iCodeText On codetext; Property code As %String(MAXLEN = 2000); Property codetext As %String(MAXLEN = 2000) [ SqlFieldName = code_1_text ]; /// d ##class(dc.a).Test() ClassMethod Test(N = {5e6}) { s t=$zh d DISABLE^%NOJRN k ^dc.aD,^dc.aI f i=1:1:N s c=i-1#1000+1,^dc.aD(i)=$lb("",c,"code_1_text_"_c) s ^dc.aD=N d ENABLE^%NOJRN w "(time) insert = ",$zh-t,! s t=$zh d ..%BuildIndices(,,,$$$NO) w "(time) %BuildIndices = ",$zh-t,! s t=$zh d $system.SQL.TuneTable("dc.observation_lab",,1,,,,,,,"100%") ;&sql(TUNE TABLE dc.observation_lab %SAMPLE_PERCENT '100%') w "(time) tune table = ",$zh-t,! } } The following query does not use iCode/iCodeText indexes (2025.2.CE): select code_1_text, count(code_1_text) from dc.observation_lab group by code_1_text order by 2 desc PS: if possible, I would try to convert the text into a number in some way and index this number already, perhaps even with the bitmap type.
go to post Vitaliy Serdtsev · Aug 4 I think this should be addressed to the WRC rather than the Ideas Portal. Also, @Robert Cemper has already registered WRC #1002589 and @Evgeny Shvarov most likely has too.
go to post Vitaliy Serdtsev · Aug 4 I completely agree with you.👍 I hope someone from InterSystems will pay attention to your post. PS: and in addition, it would also be nice to solve the issue with %FromOref(): either the code or the documentation needs to be fixed. On version 2025.2.CE it still doesn't work.
go to post Vitaliy Serdtsev · Aug 4 How to Change Your Primary Email Address on Developer Ecosystem Resources
go to post Vitaliy Serdtsev · Aug 4 Here explained to us that this is not a bug, but a feature: <PROTECT> *Function not allowed in IRIS Native python Starting from 2024.1 IRIS Native disallows routine invocations. Please use class methods instead. For reference, these changes can be identified as DP-422635 and DP-424156. PS: and yes, additional roles and resources like %Native_*/%All etc. no eliminate the <PROTECT> error. Checked on version 2025.2.CE
go to post Vitaliy Serdtsev · Jul 16 Very strange syntax: But if we tried at once with a single statment with a select into (1 value) it fails INSERT INTO Sample.YoungPeople (PASReligionCode) values (SELECT internalPatientNumber FROM Pennine_TIE_Clinicom_Link.PMISPECIALREGNCA where InternalPatientNumber=100) See: Insert Data from Another Table Using a SELECT Query %SYSTEM.SQL.Schema:CreateLinkedTable() Defining a Table by Querying an Existing Table %SYSTEM.SQL:QueryToTable()deprecated %SYSTEM.SQL.Schema:QueryToTable()deprecated