go to post Vitaliy Serdtsev · Aug 3, 2022 I have already written, but I will repeat again: not everyone can download from WRC, but only registered customers with paid technical support. There is an exception only for downloading the Community Edition version from WRC through the service evaluation.intersystems.com
go to post Vitaliy Serdtsev · Aug 3, 2022 The very first message contains a link from where you can download the ODBC-2022.1.0.209.0 driver for different operating systems.
go to post Vitaliy Serdtsev · Aug 3, 2022 What does the JDBC driver have to do with the question about the ODBC driver? Unlike JDBC, the ODBC driver still yet needs to be registered in the OS (at least for Windows), which is what the installer does.
go to post Vitaliy Serdtsev · Jul 27, 2022 And can do it even easier by using a ready-made method Base64FromStream()
go to post Vitaliy Serdtsev · Jul 25, 2022 I checked on version 2022.2CE & Win11 - everything is displayed as it should.
go to post Vitaliy Serdtsev · Jul 19, 2022 Made some minor changes to your code and now everything works as expected. ClassMethod ActivateSQL(customerId) As %Status { ... Quit $$$OK } ClassMethod ActivateOO(customerId) As %Status { ... Quit $$$OK } If mode=0 { Do $system.OBJ.DisplayError(objCust.ActivateOO(id)) } else { Do $system.OBJ.DisplayError(objCust.ActivateSQL(id)) Set objCust.Active = objCust.ActiveGetStored(id) } Or If mode=0 { Do $system.OBJ.DisplayError(objCust.ActivateOO(id)) } else { Do $system.OBJ.DisplayError(objCust.ActivateSQL(id)) Do objCust.%Reload() }
go to post Vitaliy Serdtsev · Jul 19, 2022 If this feature is not available in the Community Edition, then it makes no sense for me to try it. I just thought that in the preview version, all the features for testing are available. But thanks anyway for the quick response.
go to post Vitaliy Serdtsev · Jul 19, 2022 Let's say you need to write a classmethod that updates a single property. Update where: in memory or on disk? Using SQL, you cannot update the value of a field in memory, but only on disk. On the other hand, OpenId() reads data from disk and knows nothing about the changes on disk that occurred after its call. To avoid confusion, I would look to the side Version Checking (Alternative to Concurrency Argument) or/and <propertyname>GetStored()
go to post Vitaliy Serdtsev · Jul 19, 2022 I decided to try Columnar Storage (IRIS CE): Property p As %String(STORAGEDEFAULT = "columnar");When compiling a class, I get the following error: ERROR #15804: Columnar Storage (STORAGEDEFAULT=COLUMNAR) is not available with this license I turn to the documentation to find out what's the matter: Error Codes 15000 and Higher There is no description of error #15804 next, I check the current license restrictions: InterSystems IRIS Community Edition Limitations There are no Columnar Storage restrictions
go to post Vitaliy Serdtsev · Jul 19, 2022 See: %OpenId(id As %String = "", concurrency As %Integer = -1, ...) Object Concurrency Options or Version Checking (Alternative to Concurrency Argument)
go to post Vitaliy Serdtsev · Jul 8, 2022 size = 201 (single line) ClassMethod Convert(a As %String) As %String { s x=$lfs("A,4,@,B,|3,8,C,(,<,E,3,€,G,9,6,I,|,],K,|<,|{,L,1,£,O,0,*,S,5,$,T,7,+,X,><,}{,Z,2,~/_") f i=1:1:$l(a){s c=$e(a,i),p=$lf(x,$$$UPPER(c)) s:p k(p)=3-$g(k(p),2),c=$li(x,p+k(p)) s r=$g(r)_c} q r }
go to post Vitaliy Serdtsev · Jul 8, 2022 Check for "ZzX" Instead of "2~/_X", there should be "2~/_><"
go to post Vitaliy Serdtsev · Jul 1, 2022 See RuntimeMode: s rs=##class(%ResultSet).%New("%DynamicQuery:SQL") s rs.RuntimeMode=1 ;or 2
go to post Vitaliy Serdtsev · Jun 30, 2022 parameter INDEXNULLMARKER; Override this parameter value to specify what value should be used as a null marker when a property of the type is used in a subscript of an index map. The default null marker used is -1E14, if none is specfied for the datatype. However %Library.PosixTime and %Library.BigInt datatypes could have values that collate before -1E14, and this means null values would not sort before all non-NULL values. For beauty, I would also use the value of this parameter, for example: Class dc.test Extends %Persistent { Property idp As dc.test; Property idpC As %Integer(INDEXNULLMARKER = "$c(0)") [ Calculated, Private, Required, SqlComputeCode = {s {*}=$s({idp}="":$c(0),1:{idp})}, SqlComputed ]; Property Name As %String [ Required ]; Index iUnq On (idpC, Name) [ Unique ]; ClassMethod Test() { d ..%KillExtent() &sql(insert into dc.test(Name,idp)values('n1',1)) w SQLCODE,! ;0 &sql(insert into dc.test(Name,idp)values('n2',1)) w SQLCODE,! ;0 &sql(insert into dc.test(Name,idp)values('n2',1)) w SQLCODE,!! ;-119 &sql(insert into dc.test(Name,idp)values('n1',null)) w SQLCODE,! ;0 &sql(insert into dc.test(Name,idp)values('n2',null)) w SQLCODE,! ;0 &sql(insert into dc.test(Name,idp)values('n2',null)) w SQLCODE,!! ;-119 zw ^dc.testD,^dc.testI } }Output: USER>d ##class(dc.test).Test() 0 0 -119 0 0 -119 ^dc.testD=4 ^dc.testD(1)=$lb("",1,"n1") ^dc.testD(2)=$lb("",1,"n2") ^dc.testD(3)=$lb("","","n1") ^dc.testD(4)=$lb("","","n2") ^dc.testI("iUnq",1," N1",1)="" ^dc.testI("iUnq",1," N2",2)="" ^dc.testI("iUnq",$c(0)," N1",3)="" ^dc.testI("iUnq",$c(0)," N2",4)=""Or Property idpC As %Integer [ Calculated, Private, Required, SqlComputeCode = {s {*}=$s({idp}="":$$$NULLSubscriptMarker,1:{idp})}, SqlComputed ];Output: USER>d ##class(dc.test).Test() 0 0 -119 0 0 -119 ^dc.testD=4 ^dc.testD(1)=$lb("",1,"n1") ^dc.testD(2)=$lb("",1,"n2") ^dc.testD(3)=$lb("","","n1") ^dc.testD(4)=$lb("","","n2") ^dc.testI("iUnq",-100000000000000," N1",3)="" ^dc.testI("iUnq",-100000000000000," N2",4)="" ^dc.testI("iUnq",1," N1",1)="" ^dc.testI("iUnq",1," N2",2)=""
go to post Vitaliy Serdtsev · Jun 30, 2022 Class dc.test Extends (%RegisteredObject, %JSON.Adaptor) { Parameter %JSONENABLED = 1; Property AppointmentID As %String(%JSONFIELDNAME = "AppointmentID", %JSONINCLUDE = "inout"); Property AppointmentType As %String(%JSONINCLUDE = "inout"); Property AppointmentTypeID As %String(%JSONINCLUDE = "inout"); Property Date As %String(%JSONINCLUDE = "inout"); Property DepartmentID As %String(%JSONINCLUDE = "inout"); Property Duration As %Integer(%JSONINCLUDE = "inout"); Property PatientAppointmentTypeName As %String(%JSONINCLUDE = "inout"); Property LocalProviderID As %String(%JSONINCLUDE = "inout"); Property ProviderID As %String(%JSONINCLUDE = "inout"); Property StartTime As %String(%JSONINCLUDE = "inout"); Property Reason As %String(%JSONINCLUDE = "inout"); XData AthenaAppointment { <Mapping xmlns="http://www.intersystems.com/jsonmapping"> <Property Name="AppointmentID" FieldName="appointmentid" /> <Property Name="AppointmentType" FieldName="appointmenttype" /> <Property Name="AppointmentTypeID" FieldName="appointmenttypeid" /> <Property Name="Date" FieldName="date" /> <Property Name="DepartmentID" FieldName="departmentid" /> <Property Name="Duration" FieldName="duration" /> <Property Name="PatientAppointmentTypeName" FieldName="patientappointmenttypename" /> <Property Name="LocalProviderID" FieldName="localproviderid" /> <Property Name="ProviderID" FieldName="providerid" /> <Property Name="StartTime" FieldName="starttime" /> <Property Name="Reason" FieldName="reasonid" /> </Mapping> } /// d ##class(dc.test).Test() ClassMethod Test() { s json="{""date"":""06/27/2022"",""appointmentid"":""1214525"",""departmentid"":""195"",""localproviderid"":""187"",""appointmenttype"":""NEW PATIENT 45"",""providerid"":""187"",""starttime"":""14:00"",""duration"":45,""appointmenttypeid"":""1188"",""reasonid"":""-1"",""patientappointmenttypename"":""New Patient""}" try{ s tmp=..%New() $$$ThrowOnError(tmp.%JSONImport(json,"AthenaAppointment")) $$$ThrowOnError($system.OBJ.Dump(tmp)) }catch(ex){ #dim ex As %Exception.AbstractException w ex.DisplayString() } } }Output: USER>d ##class(dc.test).Test() +----------------- general information --------------- | oref value: 3 | class name: dc.test | reference count: 1 +----------------- attribute values ------------------ | AppointmentID = 1214525 | AppointmentType = "NEW PATIENT 45" | AppointmentTypeID = 1188 | Date = "06/27/2022" | DepartmentID = 195 | Duration = 45 | LocalProviderID = 187 |PatientAppointmentTypeName = "New Patient" | ProviderID = 187 | Reason = -1 | StartTime = "14:00" +-----------------------------------------------------PS: pay special attention to the reason field: is it a string or an array of strings?
go to post Vitaliy Serdtsev · Jun 30, 2022 The new version of IRIS 2022.2 has a new feature Columnar Storage, about which the documentation says the following: Choosing a storage layout is not an exact science. You might need to experiment with multiple layouts and run multiple query tests to find the optimal one. Therefore, you are unlikely to find an exact answer to your question. Usually, the more efficient the query is and there are "correct" indexes, the smaller the GREF and, accordingly, the shorter the execution time. But this is influenced by many factors, not just the above: see InterSystems SQL Optimization Guide
go to post Vitaliy Serdtsev · Jun 30, 2022 This can be done much easier, for example: Include %occUtility Class dc.test Extends %Persistent [ ClassType = persistent, ProcedureBlock, SqlTableName = demo ] { Property Foo As %String [ SqlFieldName = FooBar ]; Property Bar As %Boolean; ClassMethod Test() { ; d ##class(dc.test).Test() d ..%KillExtent() &sql(insert into dc.demo(FooBar,Bar)values('f1',0)) &sql(insert into dc.demo(FooBar,Bar)values('f2',1)) &sql(insert into dc.demo(FooBar,Bar)values('f3',null)) s tablename=$$$comClassKeyGet(..%ClassName(1),$$$cCLASSsqlqualifiednameQ) s rs=##class(%ResultSet).%New("%DynamicQuery:SQL") d rs.Prepare("select * from "_tablename) d rs.Execute() while rs.Next() { w ! f i=1:1:rs.GetColumnCount() w rs.GetColumnHeader(i)," = ",$$quote(rs.GetData(i))," " } d rs.%Close() } }Output: USER>d ##class(dc.test).Test() ID = 1 Bar = 0 FooBar = "f1" ID = 2 Bar = 1 FooBar = "f2" ID = 3 Bar = "" FooBar = "f3"
go to post Vitaliy Serdtsev · Jun 28, 2022 Caché 5.0.21: Class DC.DemoPropertyQuery Extends %Persistent [ ClassType = persistent, ProcedureBlock ] { Property Foo As %String; Property Bar As %Boolean; ClassMethod Benchmark() { set Job=##CLASS(%SYSTEM.Process).%OpenId($job) set start = $zhorolog set startGlobalRefs = Job.GlobalReferences set startLines = Job.LinesExecuted for i=1:1:1000 { kill properties do ..GetPropertiesAsQuickly(.properties) } set endLines = Job.LinesExecuted set endGlobalRefs = Job.GlobalReferences write "Elapsed time (1000x): ",($zhorolog-start)," seconds; ",(endGlobalRefs-startGlobalRefs)," global references; ",(endLines-startLines)," routine lines",! do ..Print(.properties) write ! } ClassMethod Print(ByRef properties) { set key = "" for { set key = $order(properties(key),1,data) quit:key="" set $listbuild(type,origin) = data write !,"property: ",key,"; type: ",type,"; origin: ",origin } } ClassMethod GetPropertiesAsQuickly(Output properties) { // Getting properties via macro-wrapped direct global references is harder to read, // but is the fastest way to do it. set key = "" set class = ..%ClassName(1) for { set key = $$$comMemberNext(class,$$$cCLASSproperty,key) quit:key="" set type = $$$comMemberKeyGet(class,$$$cCLASSproperty,key,$$$cPROPtype) set origin = $$$comMemberKeyGet(class,$$$cCLASSproperty,key,$$$cPROPorigin) set properties(key) = $listbuild(type,origin) } } }Result: USER>do ##class(DC.DemoPropertyQuery).Benchmark() Elapsed time (1000x): .018047 seconds; 25003 global references; 40000 routine lines property: %Concurrency; type: %Library.CacheString; origin: %Library.Persistent property: %IsInSave; type: %Library.CacheString; origin: %Library.Persistent property: Bar; type: %Library.Boolean; origin: DC.DemoPropertyQuery property: Foo; type: %Library.String; origin: DC.DemoPropertyQuery