go to post Julius Kavay · Dec 21, 2019 You could try this way (I assume, your image is in *.jpg, *.png, *.gif, *.ico or *.bmp format and you use a Windows OS): - save the stream to a temp file - do $zf(-1,"pathToIrfanView.exe pathToInpFile /resize=(100,100) /aspectratio /convert=pathToOutFile") - read the output into a stream and proceed as needed Don't forget, if one of the above path contains a space char, you have to put in quotes the whole path. /resize=(100,100) /aspectration means, the picture will be resized to a max width/height of 100 by maintaning the aspect ratio. Example: input=2000x3000 out =67x100, input=3000x2000 out=100x67 For Unix exists similar tools to use with $zf(-1,...), for example "identify" to get the dimensions of the picture and "convert" or "imagemagick" for resizing.
go to post Julius Kavay · Dec 21, 2019 As I wrote above, Java is not my case, sorry. Maybe the link below gives you some clue https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_javagateway
go to post Julius Kavay · Dec 21, 2019 I'm not that java guy, so just a hint only. There should be a public static java.lang.String PetNameLogicalToDisplay(...) method, so use/call this method to display your pets.
go to post Julius Kavay · Sep 22, 2019 If your routine works in a terminal session (by issuing a DO ^Routinname command) but does not work, when the same routine is started via the Job commannd (JOB ^Routinname) then you lack something in background, what you have in the foreground. Put an errortrap in your routine and simple report a possible error (and if you wich, additionally the execution progress of your routine). rvExt2012 ; Test set $zt="bgErr" // ... // ... do signal("checkpoint 1") // this is optional // ... // ... do signal("checkpoint 2") // this is optional // ... // ... do signal("Done") quit bgErr do signal("Error: "_$ze) quit signal(msg) do $system.Event.Signal($zp, $username_", "_$roles_", "_msg) quit Now, in the terminal session enter following line job ^rvExt2012 do { set $lb(s,m)=$system.Event.WaitMsg("",1) write m,! } while s
go to post Julius Kavay · Sep 14, 2019 By the way, he above works for unicode chars too, unless your pattern match table is outdated ;-))Another solution is to use an loop and RegEx: set str="abcd(123)/,op(56)*&^%$987ABC", i=0 set remove="[:punct:]|[:symbol:]" set keep = "()" while $locate(str,remove,i,i,c) { set:keep'[c $e(str,i-1)=" " }
go to post Julius Kavay · Sep 14, 2019 A little bit $translate(), a little bit of $zstrip() and the job is done (in the example below, I want to keep parenthesis) set str="abcd(123)/,op(56)*&^%$987ABC" write $tr(str,$zstrip(str,"*AN","()"),$j("",$l(str))) what to keep generell ------^^^ what to keep extra --------------^^
go to post Julius Kavay · Sep 10, 2019 The intention behind my post was, to give you one idea (of many other possibilities), how to convert XML to CSV. A empty (chars) element is just one of some other unhandled cases (missing tags, other tags inside of COLx tag, etc.).If you need some speed and your XML-File obeys following constraints:- the file is a correct XML-File- contains only the 'Data', 'Details' and 'ColX' tags- no selfclosing tags, like <sometag/>then you could try the QAD-way (quick-and-dirty) of conversion.Again, below an example routine (without excessive testing).All ISC people and ordinary programer, please look the other way ;-)) Convert() Public { set len=32000 // chunk size, a safe value is: // 32767 - longestColumnValue - tagSizes set fi="c:\temp\example-t.xml" // inp file (xml) set fo="c:\temp\example-t.csv" // output file (csv) open fi:"ru":1 open:$t fo:"nw":1 if '$t close fi quit set xml=$$inp(fi,len) // first xml-chunk set i=0, p=0 while 1 { set i=$locate(xml,"\<\/?\w+\>",i,j,v) // next (opening or closing) tag if i { // let see, what we got if v="<Details>" { set row="", p=-1 // start a new row } elseif v="</Details>" { d out(fo,row) s p=0 // complete, write out } elseif p,v["<Col" { s p=j, o=$zstrip(v,"*AP") // new column, keep start } elseif p,v["</Col" {s $li(row,o)=$$val($e(xml,p,i-1)) // get value } // everything else is don't care set i=j } else { set tmp=$$inp(fi,len) // next xml-chunk if tmp="" quit // done // remove processed data, add new one if p>0 { set xml=$e(xml,p,*)_tmp,p=1,i=0 } else { s xml=$e(xml,i,*)_tmp,i=0 } } } close fi close fo } val(val) { quit $zstrip(val,"<>w") // add handling of charcter entities like < etc. } out(fo,row) { use fo write $listtostring(row,";",1),! // delimiter! } inp(fn,len) { use fn try { read xml#len } catch { s xml="" } // in case, $zeof-mode is off quit xml } The above converter reads a simple test XML-file with two million 'ColX' items in 5 seconds and creates a CSV file with 100000 rows and 20 columns (in each row). Instead of file you can also use an stream.
go to post Julius Kavay · Sep 9, 2019 If you "donate" your XML-File a version info and an extra root-node: <?xml version="1.0" encoding="UTF-8" ?> <Data> <Details> ... </Details> </Data> and use, for example, the %XML.Textreader class (see belov). Then with few lines of code the job is done: XML ; XML to CSV #define ROOT "Data" #define DEL ";" ##; your CSV-delimiter, $c(9) or ";" or ... #; set inpFile="c:\temp\example.xml" set outFile="c:\temp\example.csv" if ##class(%XML.TextReader).ParseFile(inpFile, .rdr) { if rdr.Read(), rdr.NodeType="element", rdr.Name=$$$ROOT { open outFile:"nw":1 if $t { use outFile while rdr.Read() { if rdr.NodeType="element",rdr.Name="Details" { set line="" } elseif rdr.NodeType="chars" { set line=line_$lb(rdr.Value) } elseif rdr.NodeType="endelement",rdr.Name="Details" { w $lts(line,$$$DEL),! } elseif rdr.NodeType="endelement",rdr.Name=$$$ROOT { close outFile quit } } } else { w "file open problem",! } } else { w "XML root-element problem",! } } else { w "XML structure problem",! }
go to post Julius Kavay · Sep 8, 2019 The short answer is: NO.The long answer is:if you try to make a trick, like the below code: it won't work. ClassMethod name() { set mynull={"def":null} set result={"value1":123, "value2":(mynull.def) } quit result } now the surprise: write mynull.%GetTypeOf("def") ---> null write result.%GetTypeOf("value2") --> string
go to post Julius Kavay · Sep 8, 2019 It will depend on the structure of your xml file (next time a short sample would be helpfull).Usually, you can do it with the help of %XLM.TextReader / %XML.Reader class.
go to post Julius Kavay · Sep 6, 2019 Do you really think it makes a difference if my routine contains "set xx=xx+1" instead of "set xx=1+xx"?If yes, try the following: Times2 ; execution time measurement s num=0,t=$zh f i=1:1:1E6 { s num=num+1 } w $j($zh-t,8,6),! s num=0,t=$zh f i=1:1:1E6 { s num=num+1 } w $j($zh-t,8,6),! q my output values are USER>d ^Times2 0.047048 0.038218 USER>d ^Times2 0.034727 0.035160 USER>d ^Times2 0.044252 0.036175 USER>d ^Times2 0.045639 0.035366 Both loops are exactly the same! And now, please explain why the times are partly more than 20% different?
go to post Julius Kavay · Sep 5, 2019 With time measurements keep in mind:- usually, you are not alone on a Cache server There are many other processes, some of them belongs to Cache other to the OS - the time resolution (whatever you use: $now(), $zh) is also limited- it depends also on the time, how long your mesurement runs (you are not alone!) This is my short testroutine: Times(iter=1E3,count=4) ; show times w ?3,"count num+1 1+num =$i() $i()",! w ?15,"times in microseconds",! w $tr($j("",40)," ",-1),! f i=1:1:count d time(iter) s iter=iter*10 q time(iter) { s f=1E6/iter // factor for "one operation in microseconds" w $j(iter,8) s num=0,t=$zh f i=1:1:iter { s num=num+1 } d t($zh-t*f) s num=0,t=$zh f i=1:1:iter { s num=1+num } d t($zh-t*f) s num=0,t=$zh f i=1:1:iter { s num=$i(num) } d t($zh-t*f) s num=0,t=$zh f i=1:1:iter { i $i(num) } d t($zh-t*f) w ! } t(t) { w $j(t,8,3) } and this is the output USER>d ^Times(1,8) count num+1 1+num =$i() $i() times in microseconds ---------------------------------------- 1 2.000 1.000 2.000 1.000 10 0.100 0.100 0.100 0.200 100 0.030 0.030 0.080 0.080 1000 0.044 0.042 0.088 0.090 10000 0.028 0.028 0.075 0.077 100000 0.027 0.027 0.064 0.050 1000000 0.018 0.014 0.031 0.032 10000000 0.011 0.011 0.031 0.032 USER>d ^Times(1,8) count num+1 1+num =$i() $i() times in microseconds ---------------------------------------- 1 4.000 0.000 2.000 1.000 10 0.100 0.100 0.100 0.100 100 0.040 0.030 0.080 0.580 1000 0.044 0.041 0.088 0.088 10000 0.028 0.028 0.075 0.077 100000 0.027 0.027 0.073 0.076 1000000 0.027 0.021 0.032 0.032 10000000 0.011 0.011 0.031 0.032 USER>d ^Times(1,8) count num+1 1+num =$i() $i() times in microseconds ---------------------------------------- 1 3.000 1.000 2.000 1.000 10 0.100 0.000 0.100 0.100 100 0.040 0.030 0.080 0.590 1000 0.045 0.041 0.088 0.090 10000 0.028 0.028 0.075 0.077 100000 0.027 0.027 0.073 0.075 1000000 0.015 0.012 0.031 0.032 10000000 0.011 0.011 0.031 0.032 USER> USER> USER>d ^Times(1,8) count num+1 1+num =$i() $i() times in microseconds ---------------------------------------- 1 3.000 0.000 3.000 1.000 10 0.100 0.000 0.100 0.100 100 0.030 0.030 0.080 0.630 1000 0.046 0.042 0.088 0.090 10000 0.028 0.028 0.075 0.077 100000 0.027 0.027 0.073 0.075 1000000 0.014 0.012 0.032 0.032 10000000 0.011 0.011 0.031 0.032 USER> I consider time measurements only as a rough approximations
go to post Julius Kavay · Sep 4, 2019 If you want to detect a journal change, it means, you want to do something, when such a change took place.I think, you could do something like this:a) Start a process at system start (for example, from %ZSTART), which will handle journal changesb) In that process, get the current journal filec) try to open this filed) if (c) fails, wait a few seconds and then goto c)e) if (c) succeds, handle journal file change, then goto b) A simplified routine, but untested (as a suggestion): journalchanges ; Handle journal file changes #define SWITCHES $system.Util.GetSwitch() #define SHUTDOWN ##Expression(2**16) #define BITAND(%a,%b) $zboolean(%a,%b,1) set jouFile=$$getCurrentFile() // get the current journal file if jouFile="" Quit // should not happen, but who knows... while '$$$BITAND($$$SWITCHES, $$$SHUTDOWN) { // stop, if shutdown is in progress open jouFile:"WL":1 // try to get ownership continue:'$test // locked (by the journaling system), we try once again close jouFile // because we were interested in status only // Now you can use <jouFile> to handle the file change // By now, he journaling system uses a new journal file set jouFile=$$getCurrentFile() // get the new journal file if jouFile = "" quit // just to be on the safe side } quit // we are done getCurrentFile() { try { return ##class(%SYS.Journal.System).GetCurrentFile().Name } catch { return "" } }
go to post Julius Kavay · Aug 26, 2019 Yes, you have right, thank you for the hint. One never should add an alternate function without testing it!The correct form is: ClassMethod CountQ(node) As %Integer { s end=node if $data(@node)#10 { set sum=1 } else { set sum=0 } while 1 { set node=$query(@node) quit:node=""||($name(@node,$qlength(end))'=end) if $increment(sum) } quit sum }
go to post Julius Kavay · Aug 24, 2019 Class community.counter Extends %RegisteredObject { /// Example: /// set ^x(1)=111 /// set ^x(3,5)=222 /// set ^x(3,7)=333 /// /// The above global has 5 nodes: /// ^x without a value /// ^x(1) with value /// ^x(3) without a value /// ^x(3,5) with value /// ^x(3,7) with value /// /// write ##class(community.counter).CountQ($name(^x)) --> 3 /// write ##class(community.counter).CountR($name(^x)) --> 3 /// /// Using your example: /// write ##class(community.counter).CountQ($name(^Locations)) --> 5 /// write ##class(community.counter).CountQ($name(^Locations("USA")) --> 3 /// /// /// N.B. /// Recursion is a tricky thing! /// It helps one to get a clearly laid out solution /// but you should take care about runtimes. /// /// CountQ(...) is about 4-5 times faster then CountR(...) /// /// -------------------------------------------------------- /// /// Return the count of nodes of a global- or a local variable /// which have a value, using $QUERY() function /// /// node: /// a local or global variable, example: $na(^myGloabl), $na(abc) /// or a local or global reference example: $na(^myGlobal(1,2)) /// ClassMethod CountQ(node) As %Integer { if $data(@node)#10 { set sum=1 } else { set sum=0 } while 1 { set node=$query(@node) quit:node="" if $increment(sum) } quit sum } /// Return the count of nodes of a global- or a local variable /// which have a value, using recursion, using recursion /// /// node: /// a local or global variable, example: $na(^myGlobal), $na(abc) /// or a local or global reference example: $na(^myGlobal(1,2)) /// ClassMethod CountR(node) As %Integer { set sum=0 do ..nodeCnt($name(@node), .sum) quit sum } ClassMethod nodeCnt(ref, ByRef sum) As %Integer [ Internal, Private ] { if $data(@ref)#10, $increment(sum) set i="" while 1 { set i=$order(@ref@(i)) quit:i="" do ..nodeCnt($na(@ref@(i)),.sum) } } }
go to post Julius Kavay · Aug 19, 2019 Of course, the same goes for the other methods, which have a wide (...W) variant
go to post Julius Kavay · Aug 19, 2019 I can see it right now, do you use - conn.Prepare(...) or - conn.PrepareW(...) ? This should be coordinated with your MySQL installation.
go to post Julius Kavay · Aug 19, 2019 Some hints/questions: did you installed the correct driver? I mean, do have Cache/Iris and the driver the same architecture (32 vs. 64 bit)? I'm not an MySQL expert (I do not even have an MySQL DB), so I ask, is there any problem with the character size (1 byte vs. 2 bytes/unicode), if this applies? with a DB-Tool, like WinSQL, try to make an SELECT (as suggested by Eduard Lebedyuk) statement. What is the error message?
go to post Julius Kavay · Aug 16, 2019 HELP: what are the markdown characters? In the above answer, I put some words between angle braces, now all they are lost! OK, I try once again with an apostrophe. 1) set stat=conn.Connect("odbcname", "username" ,"password") "username" is a MySQL user. 5) If the content of the variable "variableX" is an alphanumeric value then put a single quote char (') around the value. Beforehand remove (or replace) all single quotes (with something else) from "variableX".