That's precisely the intended meaning of orthogonal in this context. All four combinations of public/private and class/instance are distinctly meaningful and useful in their own right. The concepts are separate, independent.
- Log in to post comments
That's precisely the intended meaning of orthogonal in this context. All four combinations of public/private and class/instance are distinctly meaningful and useful in their own right. The concepts are separate, independent.
Argumentless DO is still the simplest way to introduce a scope to NEW a variable, including $namespace or $roles. Yes, you can extract that out to another procedure or method, but I often prefer to do it inline.
$double and dynamic objects also poke holes in the idea that everything is a string:
USER>w [1,"2"].%ToJSON()
[1,"2"]
USER>s d=1,b=$double(d) w d," ",d/3,!,b," ",b/3
1 .3333333333333333333
1 .33333333333333331482
You can use the $ziswide intrinsic function to check whether a global is portable to an eight-bit instance.
I encourage you to get in touch with the WRC, but if you post more information, we might be able to make some progress. For starters, what version of Caché and Python, and what kind of errors are you seeing?
I successfully built the binding using the following:
It looks like I got a total of eleven compiler warnings.
As described here, it's a bit tricky to actually use the binding with the system version of Python due to Apple's System Integrity Protection (SIP):
This may be fixable with some install_name_tool surgery, but a separate installation is recommended.
Yes, if you're getting errors about print in Python 3, I second Iain's suggestion to look for the setup3.py script. I just did this successfully using an Anaconda 4.4 install of Python 3.6.1.
Compared to a delimited string, lists have the overhead of storing the length of each element, typically one extra byte. Numbers and Unicode characters are also stored differently, sometimes more efficiently, sometimes less. Otherwise, there is no difference between fetching a delimited string or a list.
The DataBlkRd and DataBlkBuf columns shows that ^StringGlobal was read entirely from global buffers, whereas ^ListGlobal had to read over 9,000 blocks. In each case, it seems that the global occupies about 17,000 blocks; about 136 MB, assuming 8 KB blocks.
I suggest that you do the following:
Based on your numbers, the first runs will be cold, and should take a minute or two. The second runs should be essentially instantaneous.
I'm not sure I'm reading this correctly, but I believe the key difference in the cold runs is 10,399 vs 5,853, again suggesting that ^ListData went to disk more often.
I'm surprised that it makes such a big difference, but I suspect what's happening here is that your copy of ^ListData into ^StringData resulted in a more space-efficient organization. You might want to look at the packing column of a detailed report from the %GSIZE utility.
It's possible that something about your data causes $list to store it less efficiently, but your data hasn't convinced me of that. If you copied ^ListData unchanged into, say, ^ListData2, my guess is that you would see a similar improvement.
The %UnitTest package is designed such that each suite stands alone: it is loaded, compiled, run, and deleted, independent of any other suite. Deleting the test classes is just part of cleaning up.
You can pass the /nodelete qualifier, or even set it as a default using $system.OBJ.SetQualifiers(). Given that deletion is the default behavior, however, I suggest that you adjust your workflow accordingly. I edit XML export files directly. Some people maintain a development and test namespace, with the classes being exported from development, and imported into test.
Your code creates a property when getting the property returns a 404. However, I'm getting a 400 when a property doesn't exist:
$ curl --user _system:SYS -w "\n***\n%{http_code}\n" 'http://127.0.0.1:52773/api/docdb/v1/DEMO/prop/DEMO.TEST11/Ergebniszuf'
{"status":{"errors":[{"error":"ERROR #25541: DocDB Property 'Ergebniszuf' does not exist in 'Demo.TEST11'","code":25541,"domain":"%ObjectErrors","id":"DocumentDatabasePropertyNotValid","params":["Demo.TEST11","Ergebniszuf"]}],"summary":"ERROR #25541: DocDB Property 'Ergebniszuf' does not exist in 'Demo.TEST11'"},"content":null}
***
400
I second the recommendation to comb through the upgrade checklist archive. A couple of big ones are that 2014.1 dropped support for database extents, and for 2 KB databases.
%DynamicAbstractObject is not intended to be subclassed by end users. It serves as a base for %DynamicArray and %DynamicObject, which provide JSON-style dynamic objects without a fixed schema.
You seem to be looking for a way to map between JSON and plain old registered objects. We haven't yet released such a feature, but you can do something kind of similar using DocDB, which I think first shipped in IRIS 2018.1:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GDOCDB
This feature helps to define a class that stores a JSON document in a persistent object and extract fields from the document into properties of the object.
Even if you store the current password encrypted, consider storing just the hashes for old passwords. You might use $system.Encryption.PBKDF2() for this purpose, perhaps with fewer iterations than you'd otherwise use for a live password.
The --volume and --env switches are handled by the docker command. They should come before the image name.
It looks like you're trying to run an image identified as efca5c59cbb7, but in this segment of the command line, iris is taken as the image name:
--env ICM_SENTINEL_DIR=/license iris
You're sort of back to where you were before, with Docker switches occurring after the image name, although you now have the image name in there twice. I don't have your environment, so I can't test this exact command, but I think you want something like this:
docker run -d --privileged -v /nfs/IRIS:/IRIS \
--env ISC_DATA_DIRECTORY=/IRIS/iconfig \
--env ICM_SENTINEL_DIR=/license \
-p 52774:52774 --name IRIS4 efca5c59cbb7 \
--key /IRIS/iris.key ...
If you're still having trouble, back up and build the command line incrementally. Start simple:
docker run -d --name IRIS4 efca5c59cbb7
Then add in your Docker switches (-v, -e, -p, etc.), and finally add in the IRIS arguments (--key, etc.). That way you can tell which switch or argument is causing a problem.
I'm finding it hard to read the output images, but every one of the commands that you listed has a Docker option after the image name. The form of the command should be:
docker run <Docker opts> image_name <IRIS args>
To be clear, the -e (--env), -p (--publish), and -v (--volume) switches are Docker options; they go before the image name. The --key and --before switches are IRIS arguments; they go after the image name.
Take heart, I think you're getting close. I think all you need now is to quote the arguments to the --before switch, as shown in the documentation:
--before "/usr/irissys/dev/Cloud/ICM/changePassword.sh /IRIS/pwd.txt"
If you're still having trouble, build up the command incrementally, as I previously suggested, being careful to follow the correct form of the command.
Dmitry's answer about looking at log files will also give you more information than simply noticing in docker ps that the container has exited.
Take a look at the reference for the %DynamicArray and %DynamicObject classes in the InterSystems IRIS 2019.1 preview:
https://irisdocs.intersystems.com/iris20191/csp/documatic/%25CSP.Documatic.cls
In 2019.1, you can get and set the value of a field as a stream:
USER>w ["abc"].%Get(0,,"stream").Size
3
This post about the %SyntaxColor class might be useful as a starting point:
https://community.intersystems.com/post/syntax-highlighting-objectscript
It wouldn't integrate seamlessly with the LaTeX toolchain, but you could probably transform its output into something usable.
My hunch is that XSLT is not the right tool for the job, but it's not clear to me what you're trying to do. What is the input encoding, what is the desired output encoding, and what do you mean by non-standard characters? Are these characters that don't exist in the output encoding?
So the input is Windows-1252, and the output is Windows-1252 in which certain characters are mapped to their numerical escape sequence? You could do this with XSLT 2.0 using character maps.
Given this input (presented here as UTF-8 for visibility on the forum):
<?xml version="1.0"?>
<Recordset>
• coffee €5,• tea €4
</Recordset>
This stylesheet will escape the bullets and euro signs:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:character-map name="a">
<xsl:output-character character="€" string="&#128;"/>
<xsl:output-character character="•" string="&#149;"/>
</xsl:character-map>
<xsl:output encoding="Windows-1252" indent="yes" use-character-maps="a"/>
<xsl:template match="/">
<Recordset>
<xsl:value-of select="/Recordset"/>
</Recordset>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="Windows-1252"?>
<Recordset>
• coffee €5,• tea €4
</Recordset>
I thought there was a method to do just this in the TestInstance class, but it's actually in %UnitTest.Portal package:
USER>w ##class(%UnitTest.Portal.standardPage).GetTestStatus(^UnitTest.Result)
0
Up to you if you want to depend on an implementation detail of the portal. It is a public method that's been there since 2012.
Interesting question. I think the idea is that the output is not just a number, but the second field of a $horolog/$ztimestamp string, where the convention is to include the leading zero if necessary.
If you repeat the experiment with $zdth, or you catch the value of $zts just after midnight UTC, you should see a zero after the comma.
I would look at the implementations that do not depend on a "big number" package. Java and C# use BigInteger; Python uses long; Ada, C, and others use GMP; etc. You might try porting the Pascal implementation to ObjectScript. Where you see div, use the "" operator, and be aware of operator precedence.
It occurs to me that the Visual Basic solution works with minimal modification as Caché Basic: weaken the DIM statements, change Debug.Print to Print, and replace the call to Format$().
Option Explicit
Const VECSIZE = 3350
Const BUFSIZE = 201
Dim buffer
Dim vect
Dim more, karray, num, k, l, n
For n = 1 To VECSIZE
vect(n) = 2
Next n
For n = 1 To BUFSIZE
karray = 0
For l = VECSIZE To 1 Step -1
num = 100000 * vect(l) + karray * l
karray = num \ (2 * l - 1)
vect(l) = num - karray * (2 * l - 1)
Next l
k = karray \ 100000
buffer(n) = more + k
more = karray - k * 100000
Next n
Print buffer(1)
Print "."
l = 0
For n = 2 To BUFSIZE
Print Right("00000" & buffer(n), 5)
l = l + 1
If l = 10 Then
l = 0
Print 'line feed
End If
Next n
You can also change it after installation by running cinstall setserviceusername in the bin directory.
There is a way to do something similar in Caché and IRIS. In a Russian locale, you have access to the "KOI8R" I/O translation table. KOI8-R has the funny property that if you mask out the high-order bit, you get a sort of readable transliteration. Here's an example using a Unicode instance in the "rusw" locale:
USER>s koi8=$zcvt("Пример для Кода","O","KOI8R")
USER>s ascii="" f i=1:1:$l(koi8) s ascii=ascii_$c($zb($a(koi8,i),127,1))
USER>zw ascii
ascii="pRIMER DLQ kODA"
set count=count+1 and set count=1+count generate identical object code, so I think we found your margin of error.
if $increment(count) has to set $test, so I would expect it to be slower for a local variable. (I'm not sure about a global.) In IRIS 2018.2 and later, do $increment(count) may close the gap a bit.
Interesting. I added a loop for if $increment(num) {} (i.e., a new-style if statement that doesn't set $test): no measurable improvement over legacy if.
I also added a loop for do $increment(num) (i.e., a do statement that neither sets $test nor returns a value): ever so slightly slower.
USER>d ^Times(1,8)
count num+1 1+num =$i() $i() $i(){} d $i()
times in microseconds
--------------------------------------------------------
1 1.000 0.000 1.000 0.000 0.000 1.000
10 0.000 0.000 0.100 0.100 0.000 0.000
100 0.010 0.010 0.490 0.030 0.030 0.040
1000 0.042 0.011 0.029 0.034 0.029 0.033
10000 0.011 0.010 0.030 0.032 0.032 0.031
100000 0.009 0.010 0.030 0.028 0.027 0.031
1000000 0.009 0.010 0.028 0.028 0.027 0.031
10000000 0.010 0.010 0.028 0.028 0.028 0.031
Incidentally, here are some results with num renamed to ^num:
USER>d ^Times(1,8)
count num+1 1+num =$i() $i() $i(){} d $i()
times in microseconds
--------------------------------------------------------
1 2.000 0.000 2.000 1.000 0.000 0.000
10 0.100 0.200 0.100 0.100 0.100 0.100
100 1.070 0.280 0.130 0.110 0.100 0.110
1000 0.142 0.144 0.142 0.102 0.102 0.106
10000 0.142 0.141 0.110 0.116 0.104 0.108
100000 0.142 0.141 0.102 0.101 0.100 0.104
1000000 0.139 0.140 0.100 0.098 0.100 0.102
10000000 0.138 0.138 0.098 0.098 0.099 0.102
For "=$i()", I assigned a local, rather than redundantly assigning the global.