Sunday, March 16, 2014

Counting subscripts in GTM using a simple method

Once you have many records inside your database, you may need a easy way to count your elements. There's many ways of doing that, let's look at some various techniques...
  1. using '$increment'
  2. using '+'
  3. using the 'for' parameters
The '$increment' method:
logins() ;
    n i,c
    f  s i=$o(^users(i)) q:i=""  d
    . s c=$increment(c,1)
    q c

The '+' method:
logins() ;
    n i,c
    f  s i=$o(^users(i)) q:i=""  d
    . s c=c+1
    q c

The 'for' method:
logins() ;
    n i,c
    f c=0:1 s i=$o(^users(i)) q:i=""
    q c

For me the best is the 'for' method because you can do other thing in the loop too. For example let's 'write' the counter:
GTM> f c=0:1 s i=$o(^users(i)) q:i=""  w c,!
0
1
2
3
..
58
59


Finally, look at this and train your brain to think in the GTM way:
add2(values,count)     ; w $$add2^test(.values,.count)
    n sum
    n c
    n i
    f c=0:1 s i=$o(values(i)) q:i=""  d
    . w c,") ",i,!
    . s sum=sum+i
    s count=c
    q sum


Inside a shell you test it like this:
GTM> s values(1)=""
GTM> s values(2)=""
GTM> s values(3)=""
GTM> n count
GTM> w $$add2^test(.values,.count)
0) 1
1) 2
2) 3
6
GTM> w count
3

Sharding globals with GTM

With GTM and "^variable" (globals variables), you can shard easily to handle the massive number of records. You can see that as partitioned tables for ODBC. But on steroids :)

For example we want to shard usernames and userid. Let's say that our userid is a non_neg_integer() of 10 digits. And that we want to shard on the 7 first digits...

Extracting 7 characters from a string is done using the '$e[xtract]' function:

GTM> w $extract("12345678910",0,7)
1234567

Now that you can extract characters, you can use the "_" operators to concatenate the results with whatever you want. For this experimentation we will use the "^users" global:

GTM> w "^users"_$extract("12345678910",0,7)
^users1234567


Here's the full code:
shard(userid)
    q $$%shard("users",userid)

%shard(root,id)
    n gbl
    n prefix s prefix=$e(id,0,7)
    q "^"_root_prefix


Everything from the shell:

GTM> zed "users"
[ Copy/Paste the code and exists your editor ]
GTM> zl "users"
GTM> w $$shard^users(1234567890)
^users1234567


With this new function you can easily access any userid without thinking about the shard method. You just need to use the 'indirection' notation from GTM i.e.'@variable'.

userinfo(userid)
    n gbl s gbl=$$shard(userid)
    w "Login for userid: ",userid,!
    w @gbl@("login")
    q

Saturday, March 15, 2014

The GTM $get operation

Introducing a new operation '$get' ('$g').
$get, try to retrieve the value then give it back or send its second parameter.
#GTM] s users("admin")="Administrator"
#GTM] s users("admin","password")="SecretP4ss"
#GTM] s users("admin","hint")="AntiNSQ"
#GTM] s user=$g(users("ADMIN"),"User not found")
#GTM] w user
User not found
#GTM] s user=$g(users("admin"),"User not found") w user
Administrator
#GTM]
Here's the code:

Your first GTM module

Let's create a module named 'hello' that can display 'world'.
  1. Start the client: mumps -dir
  2. Edit the file "hello": zed "hello"
  3. Write this code:  say w "hello",! q
  4. Save: :wq
  5. Compile: zl
  6. Run the code: d say^hello
  7. Enjoy !

The code in an indented version
say
  w "hello",!
  q
Here's the session:
#GTM] zed "hello"
[ INSIDE  YOUR $EDITOR ]
[ you save the file    ]
[ and quits the editor ]
#GTM] zl
#GTM] d say^hello
world

#GTM]

Some explanations:
say                   ; Name of the label
  w "hello",!         ; w[rite] the string "hello" followed by end of line: '!'
  q                   ; q[uit] return the control to the caller

You can use the fully qualified name for functions:
say                   ; Name of the label
  write "hello",!     ; w[rite] the string "hello" followed by end of line: '!'
  quit                ; q[uit] return the control to the caller

Egtm (GTM support for Erlang) using UTF-8 chset

If you've already seen this line, you know how this one can be frustrating :)
EGTM Common Error: egtm: 150373066,call^%egtmapi,%GTM-E-INVOBJ, Cannot ZLINK object file due to unexpected format,%GTM-I-TEXT, Object compiled with CHSET=UTF-8 which is different from $ZCHSET

Fighting with GTM to have the UTF8 routines of EGTM, I've finally won the round !
Here's my strategy: in rebar.config add the UTF-8 line ( and set the correct path for your gtm_dist:
{port_envs, [
  %% GT.M flags
  {".*", "gtm_dist", "/opt/application/lib/fis-gtm/V6.0-003_x86_64/utf8"},
  {".*", "gtm_chset", "UTF-8"},
  {".*", "LDFLAGS", "$LDFLAGS -I$gtm_dist -L$gtm_dist -Wl,-rpath -Wl,$gtm_dist -lgtmshr -lc"}
]}.
Then remove the 'egtm_worker.so' from the src directory, and finally recompile:
./rebar comp

Sticky