Category Archives: Technology

Converting the current date to a number in SQL

This is handy if you find yourself needing to populate a numeric timestamp field (eight digit number, yyyymmdd) with the current date.

update TheFile                                                
set TheDate = Dec(Replace(Char(current date, ISO), '-', ''), 8, 0)
where TheSelection

Obviously, TheFile is the file you are populating, TheDate is the field and TheSelection is whatever selection criteria you happen to be using.

flattr this!

Happy birthday, Mozilla

15 Years of a better web I’m a little late with this one, but on March 31st, Mozilla turned 15 years old.

Looking back, Mozilla’s plan was as radical as the Web itself: use open source and community to simultaneously create great software and build openness into the key technologies of the Internet itself. This was something commercial vendors weren’t doing and could not do. A non-profit, community-driven organization like Mozilla was needed to step up to the challenge.

When Netscape Navigator came along, it was a piece of software that you were expected to pay for. Microsoft, sensing an opportunity, not only released Internet Explorer but also bundled it – gratis – with Windows. This, in a single step, flattened Netscape’s business and left the way open for Microsoft to start stuffing proprietary technologies into their internet offerings.

If Firefox hadn’t come along when it did, and with the commitment to openness that Mozilla has maintained, we would all now be using Microsoft Internet Explorer to visit sites authored with Microsoft FrontPage and hosted on servers running Microsoft IIS. If that had happened, the web today would be a very different place in which the cost of building a web presence would be a serious barrier to the sorts of innovation we have become used to over the past 15 years.

We all owe Mozilla a debt of gratitude and the future is bright. Firefox 20 is out now and I, for one, am looking forward to seeing what Firefox OS does to the mobile market.

flattr this!

Converting dates to numbers in RPG

I keep encountering situations where I have to write a record to some painfully old file that stores a date as an integer. Converting a date to an integer is one of those tasks that is very simple to accomplish but which I never remember how to do.

So, for future reference, here is the command for converting the current date to a seven digit integer (cyymmdd format), wrapped in a bit of code that displays the results because we all like to know what we’re writing befor we write it.

H                                                                          
D DateNum         s              7s 0                                      
 /Free                                                                     
                                                                           
     DateNum = %dec(%char(%date():*cymd0):7:0);                            
     dsply DateNum;                                                        
                                                                           
     *INLR = *ON;                                                          
                                                                           
 /End-Free                                                                 

flattr this!

NewsBlur: First Impressions

As mentioned in my last post, Google Reader is no more so I decided to switch to NewsBlur. There has been a bit of a delay between the decision and implementation because the NewsBlur site clearly collapsed under the weight of the Google Reader refugees. But the responsiveness has improved and, today, I signed up.

Getting my feeds out of Google wasn’t quite as painless a process as I’d hoped. The Import From Google Reader link didn’t but (and this is to Google’s credit), it’s pretty easy to export my feeds as an xml file and (to NewsBlur’s credit) import the file. So all my feeds are loaded up and sorted into the folder structure I use.

And then I discovered that there are preferences everywhere. You can set options by site, by folder and by feed. This does give you a great deal of control over how the feeds are delivered, but it also takes a bit of getting used to.

The same can be said of the keyboard shortcuts. While many of them are logical, there are a couple that were a little unexpected – for me, at least – and I still find myself hitting the wrong button on occasion. I could just use the mouse, of course, but shortcuts – as their name implies – allow you to get to the same functionality faster.

These are minor gripes, though, and I have to say that the site handles the basic RSS requirements (speedy navigation through a large collection of stories) very well indeed. NewsBlur is also showing a great deal of potential. The most obvious of these are the social features which allow you to share stores and comment on stories that others have shared. And it’s a rather nice touch that all of your shared stories are collected on a blurblog, which will make it easy to find them again as time goes on.

Overall, I am liking NewsBlur. A lot. It’s not perfect – yet – but has gone a long way towards being everything Google Reader could have been.

flattr this!

Farewell Google Reader, Hello NewsBlur

There are times when I have the impression that Google is so determined to be social that they lose sight of the fact that their online dominance is a result of being useful. This morning was one of those times when I hopped online to check the headlines and was presented with an announcement that Google Reader is to be retired.

This is not entirely unexpected, Google seems to have been looking for an excuse to kill off their RSS reader for a while. Their reasoning seems to be that ‘social’ means kitten videos, so the community of news junkies that has built up around Reader isn’t ‘social’ and should, therefore, be killed off. With fire, if necessary.

Google have already taken steps in this direction, such as removing social features from Reader and trying to push Reader users into Google Plus, and I would be willing to guess that most users of Reader knew that the application’s days were numbered. Now we have a number: On July 1st 2013 Google Reader will be no more.

This means, of course, that I now have to pull my finger out and find an alternative. I did, briefly, consider going back to Liferea, the desktop RSS reader that I used until a few years ago, but what I really want is an online solution. I use several devices and want to be able to access the same news feed from all of them.

A quick scoot around the web turned up NewsBlur, “a social news reader with intelligence.” It’s an open-source application and the README on GitHub does provide full instructions for installing your own instance. But I’m lazy and went to look at the hosted service instead. They have two sign-up options: Free for people subscribe to fewer than 64 feeds, and $1 per month for real news junkies.

One nice feature on the site is a ‘Try out NewsBlur’ option that lets you play around with the features without committing yourself to anything. It’s a bit slow but, poking around the community feedback pages revealed that this is down to a sudden influx of visitors. Action is being taken and things should improve shortly.

$1 a month isn’t much, so I shall be signing up to NewsBlur as soon as the Import From Google Reader link stops timing out.

flattr this!

Neat Firefox trick o’the day: Viewing source code in an external editor

Being able to right click on a web page to take a look at the source code is handy but the Firefox source code viewer is a bit limited (not surprisingly really – it is just a viewer after all). Inevitably, then, there will come a time when you want to do more than just look at the source and will, therefore, need to get it into a proper text editor of some sort. You could, of course, just copy and paste but there is a better way.

You can bring up the Firefox configuration options by entering about:config in the Awesome bar and then search for view_source.

There are two configuration options you need to change:
view_source.editor.external needs to be set to true
view_source.editor.path needs to be set to the full pathname of your editor of choice

And you’re done.

flattr this!

Vim syntax highlighting for the IBM i

As you may have noticed, some of the personal projects I have mentioned on here have been written for the IBM i. I generally develop these locally in Vim and then copy the source files to a server so that I can compile and test them as and when I have a chance.

I like Vim. When I want to just sit down and get something down, Vim provides a distraction-free environment with a powerful collection of features. One of these features is syntax highlighting, and Vim comes with syntax files for a host of languages as standard. Unfortunately, RPG is not one of the languages supported out of the box.

Inevitably, however, it didn’t take much time with Google to discover that someone else had the same thought as me some time ago. So I must say thank you to Martin Rowe of DBG/400 for this rather gorgeous collection of syntax files.

flattr this!

RGZLIB – Now with online help and working compile commands

A couple of weeks ago, I talked about adding help text to CL commands. At the time, I discussed the (rather trivial) process for adding help text to the DSPOSRLS command that I wrote some time ago. Now, I have mad a bit of time to do the same for the RGZLIB command.

While doing this, I discovered that the compile commands I’d included with the README had made a few too many assumptions about the state of my library list. These instructions would work fine if your development library was at the top of your library list but, if not, you would have enciountered issues with members not found.

This is now fixed and the latest version of the README, along with a help-enabled version of the command, can now be found at the usual place.

flattr this!

Adding help text to CL commands

CL commands are handy, and they become even handier when you add enough help text for other people to get the most out of your utilities. So I’m thankful to Ted Holt of the increasingly misnamed Four Hundred Guru for pointing out just how straighforward a process this is.

Because I should, I have gone back to some of my earlier commands and started adding a bit of help text. DSPOSRLS is, admittely, a pretty trivial command as far as documentation goes – there are no parameters and the command can only be used interactively – but I have the source in front of me and the command does provide a conveniently simple place to start.

First, you need a source file in which to enter your help text.
crtsrcpf Library/qpnlsrc

The command I didn’t know about was this one: Generate Command Documentation (GENCMDDOC):

The Generate Command Documentation (GENCMDDOC) command generates an output file which contains documentation for a Control Language (CL) command. The generated file will be one of the following:

  • If *HTML is specified for the Generation options (GENOPT) parameter, the file will contain HyperText Markup Language (HTML) source. The generated file can be displayed using a standard internet browser, and conforms to HTML 4.0 specifications. The information used to generate the file is retrieved from the specified command (*CMD) object and any command help panel group (*PNLGRP) objects associated with the command.
  • If *UIM is specified for the GENOPT parameter, the file will contain User Interface Manager (UIM) source. The generated source is an outline for the online command help for the command. The information used to generate the file is retrieved only from the specified command (*CMD) object. This option is intended to simplify the task of writing online help for CL commands.

The command doesn’t write your documentation for you, but it does provide all the structure you need if you want your command to look like all the other ones on your system. It also makes it quite easy to see how the panel group syntax works.

And so, to the command:
GENCMDDOC CMD(Library/DSPOSRLS) TODIR('/qsys.lib/Library.lib/qpnlsrc.file') TOSTMF(dsposrls.mbr) GENOPT(*UIM)

This will create a member (DSPOSRLS) of type UIM in file QPNLSRC. Change the type to PNLGRP and then you can start editing the the generated text until you have something meaningful. The syntax struck me as being very reminiscient of Markdown which makes it quite easy to get up to speed.

Once you are hapy with your help text, you will need to create the panel group:
CRTPNLGRP PNLGRP(Library/DSPOSRLS) SRCFILE(Library/QPNLSRC)

And now you need to rebuild the command with the help text added:
CRTCMD CMD(Library/DSPOSRLS) PGM(*LIBL/DSPOSRLS) SRCFILE(Library/QCMDSRC) SRCMBR(*CMD) HLPPNLGRP(DSPOSRLS) HLPID(*CMD)

Because the panel group and command are separate objects, you do not need to recreate the command every time you change the panel group. The panel group can be changed as and when you notice the inevitable typos and the updated version will be loaded when you next press F1.

Having the help text baked into your command is handy enough as it is but there is one more rather neat trick worth mentioning. If, once you are happy with your help text, you enter the following command
GENCMDDOC CMD(DSPOSRLS) TODIR('/home/expatpaul') TOSTMF('dsposrls.html') GENOPT(*HTML)

… GENCMDDOC will spit out an IFS file, named dsposrls.html, with all the same text, but marked up for HTML. I have sent the file to my home directory but, if you use TODIR('/www/apachedft/htdocs'), the file will be created in the default location for HTML files that are served by the Apache HTTP server for i.

flattr this!

Flexible SQL with Query Manager on the IBM i

Back in November, I mentioned that it was possible to extract the SQL source from existing queries using the RTVQMQRY command. I have since had an opportunity to play around with the IBM i Query Manager and have found it to be a surprisingly useful reporting tool.

What is it?

According to the iQuery Management Programming pdf, Query Management is the i5/OS implementation of query management Common Programming Interface (CPI). This allows you to retrieve data from a relational database and – most usefully – control the output formatting. It does this, unsurprisingly, by splitting the data extraction (the QM Query) and presentation (the QM form).

Where is it?

Broadly speaking, there are two options you need to know about in order to use Query Manager. First there is the STRQM command which will lead you through the process of creating and maintaining Query Management queries and forms. And then there are the Query Management CL Commands, all of which can be found on menu CMDQM, and which allow you to work with and execute existing QM Queries.

Inevitably, there are multiple ways of achieving the same result. What follows is what works for me but I do recommend that, if you do want to play around with this, investigate the available options to see what works best in your environment.

Before you begin

In STRQM, take the Work with Query Manager profiles option and change the following:

  • The Default library for QM objects is initially set to *CURLIB. This is less than optimal, so I changed this to my own Development/Test library.
  • Paging down, I also found the Default query creation mode. This is initially set to Prompted (which gives you a rather painful Query/400-like interface for creating queries). I changed this to SQL.

Define your Query

There are a couple of options here. The first, and simplest, approach is to STRQM, take the Work with Query Manager queries option and then the Create option. This will give you an SEU screen into which you can enter your SQL (assuming, of course, your default query creation mode is set to SQL). The advantage of taking this approach is that this screen includes both a syntax checker and an option to execute the statement (either all, or a sample). So you can enter, validate and test your SQL, all from the same screen.

If, however, you have an unshakable aversion to SEU, you can create and edit a source member using whatever tool or tools you prefer and then use the CRTQMQRY command to create your query. Once the query is created, your source member is no longer needed.

Whichever way you do it, you will eventually end up with an object of type *QMQRY. This is your QM Query, an SQL select that can be executed with the STRQMQRY command.

And some flexibility

This is where things start to become interesting. The STRQMQRY command includes a Set variables (SETVAR) parameter which allows you to specify up to 50 variables to be set by query management before the query is run. That’s parameters in non-IBM speak. This is easier to explain with an example, so here’s an example using a couple of realy simple purchase order tables. The code for creating these tables and populating them with a couple of one-line orders is below the fold.

And so, to the query. I have, a very simple QM Query (which I have imaginatively named QMTEST) that lists all orders in the simple orders database.

The query looks like this…

select header_order_number, header_order_date,    
       line_ean_number, line_quantity, line_price 
from orderhdr                                     
join orderline on header_index = line_header_index

And the interactive result looks like this…

         HEADER_ORDER_NUMBER  HEADER_ORDER_DATE  LINE_EAN_NUMBER  LINE_QUANTITY  LINE_PRICE
         -------------------  -----------------  ---------------  -------------  ----------
000001   TST0000001           01/21/2013         1234567890123               5     27.5000 
000002   TST0000002           01/22/2013         1234567890321               4     16.5000 
******  * * * * *  E N D  O F  D A T A  * * * * *                                          

This is fine, as far as it goes, but it’s unlikely that you will ever want a list of all orders ever entered. So here’s the same QM Query with a date selection added.

select header_order_number, header_order_date,       
       line_ean_number, line_quantity, line_price    
from orderhdr                                        
join orderline on header_index = line_header_index   
where header_order_date between &FROMDATE and &TODATE

Now, if I run the query interactively, it will prompt for a from and to date. More usefully, however, I can enter a from and to date when launching the query with: STRQMQRY so that:

STRQMQRY QMQRY(QMTEST) SETVAR((FROMDATE '''01/21/2013''') (TODATE '''01/21/2013'''))

Returns this:

         HEADER_ORDER_NUMBER  HEADER_ORDER_DATE  LINE_EAN_NUMBER  LINE_QUANTITY  LINE_PRICE
         -------------------  -----------------  ---------------  -------------  ----------
000001   TST0000001           01/21/2013         1234567890123               5     27.5000 
******  * * * * *  E N D  O F  D A T A  * * * * *                                          

There are a couple of gotchas to watch out for here.

  • Because lower-case characters in variable names are changed to upper-case characters when passed to the command processing program, everything needs to be upper case.
  • If you are passing a string (or date) surrounded by quotes, you need to use triple quotes. The ouer quotes are removed and the double quotes within the value are condensed to a single quote when the value is passed to the command processing program. No, it didn’t make much sense to me either.

    You can, of course, pass a variable rather than a constant value and as soon as you do this, it really does become useful.

    Design your Form

    Now the fun begins. Having a parameterised, executable SQL object has its uses, but the QM form provides a presentation layer that allows you to format the output into something that’s almost pretty enough to put in front of your end users.

    You can edit a source member and then use the CRTQMFORM command to create your QM form, but the source is very sparse indeed. As such, I found that using the Work with Query Manager report forms option in STRQM to go through the prompts was quite useful.

    Execute anywhere

    And then you’re done. QM Queries are not a universal solution, obviously, but I have seen cases where they can be useful – most notably in conjunction with a tool such as CoolSpools that will email the QM Query, as an Excel workbook, to whatever distribution list has asked for it.

    And finally

    This started out as a really short blog post in which my only intention was to make a few notes to help me keep track of what I’m doing. As can sometimes happen, however, it grew into this monster that you have just ploughed your way through.

    Continue reading

flattr this!