go to post Julius Kavay · Apr 5, 2022 For us all, the common denominator is Cache/IRIS and we have, as you know, Cache/IRIS for Win, Linux, AIX and MAC platforms. It's nice to know about existing external tools, but for some of us the COS solutions remains as the last resort, especially if those (external) tools do not exists for the OS, one works on (Just My2Cents).
go to post Julius Kavay · Apr 4, 2022 First, as you alread wrote, changing the collation of an already existing installation is dengerious,second, as far as I know, the database creation page (of ManagementPortal) offers you "Cache/IRIS-standard" and "Cache/IRIS-standard string" only. Nevertheless, changing to "standard string" only affects the collation and not the display, i.e. string subscripts will be displayed quoted but numeric subscripts are not quoted.
go to post Julius Kavay · Mar 30, 2022 However, those legacy systems are already in operation, therefore they neither need python nor 3DES, at most, an upgrade to an current system. Hence, I don't understand your argumentation.
go to post Julius Kavay · Mar 30, 2022 Just a hint, 3DES (and DES anyway) are old technologies and shouldn't be used anymore. The following links have more (detailed) informations: https://csrc.nist.gov/news/2017/update-to-current-use-and-deprecation-of...https://www.cryptomathic.com/news-events/blog/3des-is-officially-being-r... justmy2cents
go to post Julius Kavay · Mar 17, 2022 I'm quite shure, the above code won't work as expected, or with the words of Joseph Weizenbaum: “A computer will do what you tell it to do, but that may be much different from what you had in mind.” The content of your myf variable is always 0 (the result of comparing nullstring with a filename), the size of tmpFile stream is also 0 (you never write into the stream). Sometimes it's faster to write a "oneliner" to solve a simple problem then searching and downloading a solution from openexchange or from whereever... That's the beauty of the ObjectScript. And if you think, the oneliner is worth to be reused, then make it to a method, add some small adjustments for a general usability... The oneliner s str="",tmp=##class(%File).TempFilename("txt") o tmp:"NWRU":0 i $t { u tmp zw ^||fruit s s=$zpos r:'$zseek(0) str#s c tmp:"D" } The more general version ClassMethod ToString(ref,max=32000) { s tmp=##class(%File).TempFilename("txt") o tmp:"NWRU":0 q:'$t "" u tmp zw @ref s siz=$zpos r:'$zseek(0) str#$s(siz>max:max,1:siz) c tmp:"D" q str } Use it as write ##(your.class).ToString($na(^||fruit))
go to post Julius Kavay · Feb 8, 2022 Nice and easy... That's like having an anteroom into bedroom and living room. There is always just one door open. If you want to go into bedroom, you have to brick the door of the living room and make a break through into the bedroom. The way back into living room is the same, just vice versa...
go to post Julius Kavay · Feb 1, 2022 If you ask me, it should be the responsibility of the class compiler to check table names against reserved words and to quote them, if neccessary.I think, you have closer connection to the development - what about an enhancement request?Maybe a new property, say SqlTableNameQuoted.
go to post Julius Kavay · Jan 31, 2022 First, disable the start of %ZSTART: ManagementPortal-->SystemAdmin-->Configuration-->AdditionalSettings-->Startup: here, set SystemStart to false. Now, you can (Re)Start the system and check the %ZSTART routine. <DIRECTORY> means, trying to access a nonexistent database directory. After solving the problem, set SystemStart to true.
go to post Julius Kavay · Jan 31, 2022 The simplest way is to create a classmethod, which returns the desired name: Class DC.Evgenys.Data Extends %Persistent { /// which: 0=Fullname, 1=Schemaname, 2=Tablename ClassMethod TableName(which = 0) [ CodeMode = objectgenerator ] { set sch=%compiledclass.SqlSchemaName, tab=%compiledclass.SqlTableName do %code.WriteLine($c(9)_"quit $p("""_sch_"."_tab_","_sch_","_tab_""","","",which+1)") quit $$$OK } } So you can do something like this: for i=0:1:2 write ##class(DC.Evgenys.Data).TableName(i),! DC_Evgenys.Data DC_Evgenys Data
go to post Julius Kavay · Jan 28, 2022 You forgot to take into account the $system.SQL.* variants . They make much more fun, especially because you get time for a coffee break...
go to post Julius Kavay · Jan 28, 2022 Class My.Class { Property MyProperty As %String [ReadOnly]; Method %OnNew(init As %String) As %Status [ Private, ServerOnly = 1 ] { set i%MyProperty = init } } And use it as set obj = ##class(My.Class).%New("Some initial value") write obj.MyProperty --> Some initial value set obj.MyProperty --> <CANNOT SET THIS PROPERTY>
go to post Julius Kavay · Jan 28, 2022 A possible work-around could be the class below. In short, you work with your json property as intended, merely before saving the object, you save the json-property into a stream and after opening an instance, you restore the json-property from the the stream - that's all. The drawback, no SQL over the json property... Class DC.Dyn Extends %Persistent { Property json As %DynamicObject [ Transient ]; Property jstr As %GlobalCharacterStream [ Internal, Private ]; ClassMethod MyTest(kill = 0) { if kill do ..%KillExtent(1,1) set obj=..%New() set obj.json.short="A short test text" set obj.json.maxstr=$tr($j("",$$$MaxStringLength)," ","X") do obj.json.%Set("hugedata",..stream(obj),"stream") write "Status : ",obj.%Save(),! set id=obj.%Id() write "ID : ",id,! kill (id) set obj=..%OpenId(id) write "short : ",obj.json.short,! write "maxstr : ",$e(obj.json.maxstr,1,20),"... Size: ",$length(obj.json.maxstr),! set stream=obj.json.%Get("hugedata",,"stream") write "hugedata: ",stream.Read(20),"... Size: ",stream.Size,! } ClassMethod stream(obj) { set stream=##class(%Stream.TmpCharacter).%New() do stream.Write(obj.json.short) do stream.Write(obj.json.maxstr) do stream.Write(obj.json.maxstr) quit stream } Method %OnOpen() As %Status [ Private, ServerOnly = 1 ] { if ..jstr { do ..jstr.Rewind() set ..json=##class(%DynamicAbstractObject).%FromJSON(..jstr) } Quit $$$OK } Method %OnAddToSaveSet(depth As %Integer = 3, insert As %Integer = 0, callcount As %Integer = 0) As %Status [ Private, ServerOnly = 1 ] { do ..jstr.Clear(), ..json.%ToJSON(..jstr) Quit $$$OK } } Some testing... IDEV:USER>d ##class(DC.Dyn).MyTest(1) Status : 1 ID : 1 short : A short test text maxstr : XXXXXXXXXXXXXXXXXXXX... Size: 3641144 hugedata: A short test textXXX... Size: 7282305 If your code uses obj.%Reload() then %OnReload() and %OnOpen() should contain the same code.
go to post Julius Kavay · Jan 27, 2022 Your solution is just perfect. And fast. But yes, you can avoid string manipulations... This one, for example, uses math only, merely it's neither short nor looks elegant: set dt=$h write $zd(dt,8)*100+($p(dt,",",2)\3600)*100+($p(dt,",",2)#3600\60)*100+($p(dt,",",2)#60) but gives the same result as your short and nice solution... set dt=$h write $zd(dt,8)*100+($p(dt,",",2)\3600)*100+($p(dt,",",2)#3600\60)*100+($p(dt,",",2)#60),!,$tr($zdt(dt,8)," :") On the other hand, you can install new brakes on your car, as suggested by others... ;-)) Just compare those codes with yours: set h=$h, t=$zh for i=1:1:1E6 { set x=$tr($system.SQL.TOCHAR($h,"YYYY^MM^DD^HH24^MI^SS"),"^") } write $zh-t,! set h=$h, t=$zh for i=1:1:1E6 { set x=$tr($zdt(h,8)," :") } write $zh-t,! The choice is yours...
go to post Julius Kavay · Dec 20, 2021 A simple write ##class(%SYS.Namespace).GetPackageDest(yourNsp, yourPackage) should do the trick The same goes for globals and routines write ##class(%SYS.Namespace).GetGlobalDest(yourNsp, yourPackage) write ##class(%SYS.Namespace).GetRoutineDest(yourNsp, yourPackage) if yourNsp is not provided, the current Nsp will be used