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".
go to post Julius Kavay · Aug 16, 2019 Some thoughts/hints to your problem: 1) set stat=conn.Connect(, , ) is a MySQL user. Does this user have the rights for UPDATE and INSERT? 2) What are the status codes after - set sc=conn.Prepare(...) and - set sc=conn.Execute(...)? 3) Your query-string should have blanks after the table name and also before and after the VALUES keyword. 4) If the variables value1, value2, ... valueN CAN CONATIN a backslash character then you should either duplicate them set valueX = $replace(valueX, "\", "\") or switch the escaping off at the start your query-string : set pQuery="SET sql_mode='NO_BACKSLASH_ESCAPES'; INSERT INTO ..." see also: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html 5) If the content of the variable is an alphanumeric value then put a single quote char (') around the value. Beforehand remove (or replace) all single quotes (with something else) from .
go to post Julius Kavay · Aug 15, 2019 To make a connection to a MySQL Database via ODBC is easy. In the next steps I assume you are on a Windows system (Linux/Unix is similar): 1) download (https://dev.mysql.com/downloads/connector/odbc/) and install the proper ODBC driver 2) go to ControlPanel-->AdministrativeTools-->DataSources(ODBC) 3) select the SystemDNS-Tab, click Add - give a unique name to this datasource (and remember it for step 4) - fill in the necessary fields as desired 4) use the %SQLGatewayConnection class to get/put your data from/into MySQL, something like: set gtw=##class(%SQLGatewayConnection).%New() if gtw.Connect(datasourceName, user, pass) { // do your work } else { // can't connect }
go to post Julius Kavay · Aug 13, 2019 If you work in Cache-Terminal, go to: ManagementPortal-->SystemAdmin-->Configurations-->DeviceSettings-->DeviceSubtypes Select: C-Cache-Terminal, click on Edit Go to bottom line (Caption: ZUFormFeed) and change the value from $C(27,91,72,27,91,74) to your needs. For example, if you want to retain the first and the second lines, to: $C(27,91,51,59,48,72,27,91,74). In case, your device type is not the Cache-Terminal, search for your device in ManagementPortal-->SystemAdmin-->Configurations-->DeviceSettings-->Devices Select your device, for example TERM, |TNT| or whatever device type you have. Click on edit and notice the Sub-Type. Now, as above, go to the sub-types, and change the ZUFormFeed field. In case, you wont find your device and/or device sub-type, there is a direct way too, to set the desired FormFeed (i.e. write #) and the Backspace behavior: do ##class(%Device).SetFFBS($C(27,91,51,59,48,72,27,91,74),$c(8,32,8)) The first sequence, as the method name implies, is the FormFeed sequence and the second is the Backspace sequence
go to post Julius Kavay · Aug 13, 2019 If you have your binary or character data in (sequential) global nodes, then: - create your own stream clas -in the %OnNew() method fetch the data from your global and voila, you are ready to use your data with stream methods. set ^mydata(1)="abcd" set ^mydata(2)="efgh" set ^yourdata("id",1)="1234" set ^yourdata("id",2)="5678" Class Test.Stream Extends %Stream.TmpBinary { Method %OnNew(Global, initval As %String = "") As %Status [ Private ] { Set i%%Location=$select(initval="":$$$streamGlobal,1:initval) do ..Clear() for set Global=$query(@Global,1,data) quit:Global="" do ..Write(data) do ..Rewind() Quit $$$OK } } set stream=##class(Test.Stream).%New($na(^mydata)) while 'stream.AtEnd { write stream.Read(5) } abcdefgh set stream=##class(Test.Stream).%New($na(^yourdata("id"))) while 'stream.AtEnd { write stream.Read(5) } 12345678
go to post Julius Kavay · Aug 10, 2019 set a=1.2 // your numberwrite a\1+''(a#1) // this is a NOT NOT and not a quote!
go to post Julius Kavay · Aug 1, 2019 No, it works and all installations but yes, it needs 8 Bit characters.A simple command likewrite "abcd"writes out four 8-Bit characters, independent of your installation (8-Bit or Unicode)On Evgeny Shvarov's PC, a command likewrite "Физз"would write out four 16Bit characters, in sum 2*4 = 8 characters, each with 8 Bits
go to post Julius Kavay · Jul 31, 2019 It depends on, what are the requirements... Usually we want to occupy as few (RAM) bytes as possible. Yes, it uses the fewest characters but far more bytes as Robert's solution.
go to post Julius Kavay · Jul 31, 2019 We can save some more bytes: f i=1:1:100 w $p(i_",Fizz,Buzz,FizzBuzz",",",i#5=0*2+'(i#3)+1),! "640K ought to be enough for anybody." Oh, I meant, 64 bytes should be enough.
go to post Julius Kavay · Mar 13, 2019 As Jeffrey already wrote, this is charCode x2022 (hex) but take a look at https://www.unicode.org/Public/12.0.0/charts/CodeCharts.pdf There you will find many punctuation and mathematical characters and geometric shapes. For web developers, this is like the land of plenty. My favorit characters are x2700 - x27ff (hex, of course) ✔ ✘ ✆ etc.
go to post Julius Kavay · Mar 12, 2019 If you need to reorder a given set of characters (as above, from "12/03/2019" to "2019-03-12") then the $translate(...) function, used in "backward-mode" is your best friend. set p="12/03/2019" write $tr("abcd-ef-gh","ef/gh/abcd",p) --> 2019-12-03 Your gain: 50% of speed. Nota bene (1) $translate(inputdata, fromChars, toChars) --> outputdata (2) $translate(toSequence, fromSequence, inputdata) --> outputdata Where (1) is the Forward-Mode (the regular usage) and (2) the Backward-Mode
go to post Julius Kavay · Mar 1, 2019 The correct way is: ClassMethod ind() [ PublicList = (active,reactive) ] { new active,reactive kill info // the above command (kill info) is a kind of NOP (no-operation) // at the time of entry into a methode there are no variables, // except those in the public list (if defined) set active = 1 set reactive = 2 for i="active","reactive" { set info(i)= @i } zw info break } If you want to use name-indirection in a procedure block, then - variables, used by indirection, must be made public (via PublicList) - and, depending on the situation, should be saved with the NEW command
go to post Julius Kavay · Feb 21, 2019 Maybe you want something like this: set data1 = "%sqlcq.something.value.foo" set data2 = "sqlcq.something.value.bar" for x=data1, data2 { if x ? .1"%"1"sqlcq".e { write "OK" } else { write "NOT" } w ! } Your output should be: OK OK Regards
go to post Julius Kavay · Jan 17, 2019 What do you mean with "from Code I am getting"? From which Code? ["\"KY\",\"TN\",\"AL\",\"GA\""] seems to be the same as the terminal output, except the quote chars are escaped...