go to post Vitaliy Serdtsev · Apr 26, 2022 It is very strange that the mechanism ^%SYS("CSP", "MimeFileClassify") does not work for you. According to the sources of %CSP.StreamServer, it can be seen that all the work takes place in the FileClassify method, where ^%SYS("CSP", "MimeFileClassify") is also used. I used ZEN on Caché and all was fine. Can you give a simple CSP example to reproduce your situation?
go to post Vitaliy Serdtsev · Apr 26, 2022 Try this (%Dialect): Set sqlStatement=##class(%SQL.Statement).%New(,,"MSSQL") Simple example Class dc.test Extends %Persistent { Property t As %Integer; ClassMethod Test() { d ..%KillExtent() &sql(insert into dc.test(t) values(30)) &sql(insert into dc.test(t) values(303)) zw ^dc.testD w ! s sql=2 s sql(1)="update dc.test set t=t+1 where ID=1" s sql(2)="update dc.test set t=t+2 where ID=2" s st=##class(%SQL.Statement).%New(,,"MSSQL") w "SQLCODE=",st.%ExecDirect(.st,.sql).%SQLCODE,!! zw ^dc.testD } } Output: USER>d ##class(dc.test).Test() ^dc.testD=2 ^dc.testD(1)=$lb("",30) ^dc.testD(2)=$lb("",303) SQLCODE=0 ^dc.testD=2 ^dc.testD(1)=$lb("",31) ^dc.testD(2)=$lb("",305)
go to post Vitaliy Serdtsev · Apr 18, 2022 This may be useful to you: LogRollback Transactions and Savepoints Rolling Back Incomplete Transactions
go to post Vitaliy Serdtsev · Apr 13, 2022 As I wrote above, there are two ways to solve: change TimeFormat in the locale. Query in this case will be simple. See ##class(%SYS.NLS.Format).SetFormatItem, Configuring National Language Support (NLS). complicate query. See Time-to-String Conversion Which option do you choose?
go to post Vitaliy Serdtsev · Apr 13, 2022 Rochdi, please be attentive. Above I already led an example with AVG (see spoiler "Simple sample").
go to post Vitaliy Serdtsev · Apr 13, 2022 Most likely, your locale uses TimeFormat = 2 (see tformat) You can change your locale or explicitly specify the format of the field, for example like this: Property PackingTimeSpent As %Time(FORMAT = 1);
go to post Vitaliy Serdtsev · Apr 13, 2022 What locale are you using? I use "rusw". Try to do the following in SMP: update MSDS_Serenity.KitlabelAssoc set PackingTimeSpent=35000 where label='00007IT4'then select PackingTimeSpent, %internal(PackingTimeSpent) ptsLOGICAL, %external(PackingTimeSpent) ptsDISPLAY, %odbcout(PackingTimeSpent) ptsODBC from MSDS_Serenity.KitlabelAssoc where label='00007IT4'What are your results? I have the following displayed (for DISPLAY mode): PackingTimeSpent = 09:43:20 ptsLOGICAL = 35000 ptsDISPLAY = 09:43:20 ptsODBC = 09:43:20
go to post Vitaliy Serdtsev · Apr 13, 2022 Notes on Indices Defined in Classes When working with indices in class definitions, here are some points to keep in mind: • Index definitions are only inherited from the primary (first) superclass. • ... Simple sample Class dc.Aclass [ Abstract ] { Index idxF On f; Property f As %Integer; } Class dc.test Extends (dc.Aclass, %Persistent) [ ClassType = persistent ] { ClassMethod Test() { k ^dc.testD,^dc.testI &sql(insert into dc.test(f) values(30)) &sql(insert into dc.test(f) values(303)) zw ^dc.testD,^dc.testI } } Output: USER>d ##class(dc.test).Test() ^dc.testD=2 ^dc.testD(1)=$lb("",30) ^dc.testD(2)=$lb("",303) ^dc.testI("idxF",30,1)="" ^dc.testI("idxF",303,2)=""
go to post Vitaliy Serdtsev · Apr 13, 2022 having the field defined as integer would allow selecting avg but running a query in my Zen page wouldn’t show me a time format If you the field is defined as %Integer or %String, then this is incorrect. The field type must be %Time. In this case, a time will be stored in the database as number, and the query will display the time as a string. Here is a small example: select 166 seconds,%external(cast(+166.5 as TIME)) "avg" Output: seconds = 166 avg = 00:02:46 Simple sample Class dc.test Extends %Persistent { Property t As %Time; ClassMethod Test() { d ..%KillExtent() &sql(insert into dc.test(t) values(30)) &sql(insert into dc.test(t) values(303)) zw ^dc.testD w ! s st=##class(%SQL.Statement).%New() s st.%SelectMode=2 d st.%ExecDirect(.st,"select t, %internal(t) tINT, %external(t) tSTR, avg(t) average,CAST(+avg(t) as TIME) avgSTR from dc.test").%Display() ; or w !! d ##class(%SQL.Statement).%ExecDirect(,"select t, %internal(t) tINT, %external(t) tSTR, avg(t) average,%external(CAST(+avg(t) as TIME)) avgSTR from dc.test").%Display() } } Output: USER>d ##class(dc.test).Test() ^dc.testD=2 ^dc.testD(1)=$lb("",30) ^dc.testD(2)=$lb("",303) t tINT tSTR average avgSTR 00:00:30 30 00:00:30 166.5 00:02:46 00:05:03 303 00:05:03 166.5 00:02:46 2 Rows(s) Affected t tINT tSTR average avgSTR 30 30 00:00:30 166.5 00:02:46 303 303 00:05:03 166.5 00:02:46 2 Rows(s) Affected
go to post Vitaliy Serdtsev · Apr 12, 2022 By default, data in the global is stored as glbD(ID)=$LB(%%CLASSNAME,prop1,prop2,..,propN) The total size of the string cannot exceed 3641144. Therefore, if you have a field length >3.6E6, and there are several such fields, the limit is exceeded. To work around this, you need to change storage for your class. For example so: glbD(ID)=$LB(%%CLASSNAME) glbD(ID,"prop1")=prop1 glbD(ID,"prop2")=prop2 ... glbD(ID,"propN")=propN Simple example Class dc.test Extends %Persistent { Index mySimilarityIndex On SettingsJSON(KEYS) [ Data = SettingsJSON(ELEMENTS) ]; Index mySimilaritybackupIndex On SettingsJSONbackup(KEYS) [ Data = SettingsJSONbackup(ELEMENTS) ]; Property SettingsJSON As %Text(LANGUAGECLASS = "%Text.English", MAXLEN = 3600000, SIMILARITYINDEX = "mySimilarityIndex"); Property SettingsJSONbackup As %Text(LANGUAGECLASS = "%Text.English", MAXLEN = 3600000, SIMILARITYINDEX = "mySimilaritybackupIndex"); ClassMethod Test() { d ..%KillExtent() s json=$tr($j("",3600000)," ","0") &sql(insert into dc.test(SettingsJSON,SettingsJSONbackup) values(:json,:json)) w $l(json),":",SQLCODE } Storage Default { <Data name="backup"> <Attribute>SettingsJSONbackup</Attribute> <Structure>node</Structure> <Subscript>"SettingsJSONbackup"</Subscript> </Data> <Data name="json"> <Attribute>SettingsJSON</Attribute> <Structure>node</Structure> <Subscript>"SettingsJSON"</Subscript> </Data> <Data name="testDefaultData"> <Value name="1"> <Value>%%CLASSNAME</Value> </Value> </Data> <DataLocation>^dc.testD</DataLocation> <DefaultData>testDefaultData</DefaultData> <IdLocation>^dc.testD</IdLocation> <IndexLocation>^dc.testI</IndexLocation> <StreamLocation>^dc.testS</StreamLocation> <Type>%Library.CacheStorage</Type> } }
go to post Vitaliy Serdtsev · Apr 12, 2022 Addition to the above: Indexing an Embedded Object (%SerialObject) Propertydoc
go to post Vitaliy Serdtsev · Apr 12, 2022 Choose according to your taste: #include %systemInclude s s=$c(34,34)_"te""""st"_$c(34,34) w s,!, ##class(%Global).UndoubleInnerQuotes(s),!, $$$StripQuotes(s),!, $tr(s,$c(34),"")Output: USER>d ^test ""te""st"" "te"st" "te"st" test
go to post Vitaliy Serdtsev · Apr 11, 2022 Maybe you will help the trick taken from Storing dynamic object properties larger than 3641144 symbols
go to post Vitaliy Serdtsev · Apr 11, 2022 I'm not sure if it's %Text at all. Made a small example: Class dc.test Extends %Persistent { Index mySimilarityIndex On SettingsJSON(KEYS) [ Data = SettingsJSON(ELEMENTS) ]; Property SettingsJSON As %Text(LANGUAGECLASS = "%Text.English", MAXLEN = 3600000, SIMILARITYINDEX = "mySimilarityIndex"); ClassMethod Test() { d ..%KillExtent() s json=$tr($j("",3600000)," ","0") &sql(insert into del.t(SettingsJSON) values(:json)) w $l(json),":",SQLCODE } }Output: 3600000:0
go to post Vitaliy Serdtsev · Apr 11, 2022 For %Stream.GlobalCharacter cannot use an index, but it can be used for %Text. UPD: Queries Invoking Free-text Search
go to post Vitaliy Serdtsev · Apr 11, 2022 Here's what I found: IndexClass (%Dictionary.ClassDefinition) IndexClass (%Dictionary.CompiledClass) That is, you can write something like this: Class dc.test Extends %Persistent [ IndexClass = dc.anothertest ] { }The same applies to MemberSuper. Unfortunately, I haven't found any examples of how to use it or if it works at all.
go to post Vitaliy Serdtsev · Apr 11, 2022 Class dc.test Extends %Persistent { Property F As %Integer; ClassMethod Test() { d ..%KillExtent() &sql(insert into dc.test(F) values(22)) &sql(insert into dc.test(F) values(11)) s label = "00007I0Q" &sql(select ID into :cnt from dc.test where ID = :label) w SQLCODE,":",cnt } }Output for Caché 2018.1: 100:00007I0Q Output for IRIS 2021.2: 100: PS: it is a pity that my answer was ignored.
go to post Vitaliy Serdtsev · Apr 11, 2022 Any event that occurs outside of the modal group (such as a mouse click) automatically hides the modal groupproof. Use Popup windows with modal=yes or Dialogs. PS: if you really need to use "Model Groups", then you need to do two things for this: override the method onCanEndModalHandler override the method hideGroup(). This is necessary to prohibit the close button in the upper right corner Here is a small variant: Class dс.test Extends %ZEN.Component.page { XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen"> <button caption="Show modal group" onclick="zenPage.show();"/> <modalGroup id="mgStatic" groupTitle="Popup"> <text id="mgText" label="Value:" /> <button caption="OK" onclick="zenPage.mgBtnClick();"/> </modalGroup> </page> } ClientMethod show() [ Language = javascript ] { zenPage.__canClose = false; var mg = zen('mgStatic'); mg.onCanEndModalHandler = this.onCanEndModalHandler(); mg.hideGroup=this.hideGroup; mg.show(); } ClientMethod mgBtnClick() [ Language = javascript ] { zenPage.__canClose=true; zen('mgStatic').onCanEndModalHandler=null; zenAlert('User entered: ' + zen('mgText').getValue()); // hide the modal group zenPage.endModal(); } ClientMethod onCanEndModalHandler() [ Language = javascript ] { return true; } /// Hide the group. ClientMethod hideGroup() [ Language = javascript ] { if (!zenPage.__canClose) return; if (this.groupType == 'dialog') this._canClose = true; var div = this.getFloatingDiv(); if (div) { div.style.opacity = 0; } if ((!zenIsHTML5) || (!window.TransitionEnd)) { if (!this._closing) { zenPage.endModal(); this._closing = true; } } } }