Tuesday, 27 January 2015

Objective thinking in JavaScript

It seems all too common that small projects grow to become big projects and then problems happen. Something that is very frustrating is when your JavaScript code starts to act goofy and you cannot figure out why. A lot of times it is because you are over lapping the name space and a value is getting altered in some other section of code that you did not expect. This can kill a project, it can become so hard to debug that you eventually scrap the code and move on.

Before you write a single line of JavaScript, think about how you can objectify it. In JavaScript you can wrap your code in object like statements so that name space does not get clobbered by other code.

Notice how the functions are set as variables and calls to them are invoked as if it was a real object language.



function myobject() {
   var MyVar = 0;

   this.PageSetup = function() {
      var _this = this;
   }

   this.SendCommand = function(Url) {
      var GetHttp = new XMLHttpRequest();
      GetHttp.open("GET", Url, true);
      GetHttp.send(null);
   }
}; // end of object

var myobject1 = new myobject();

myobject1.SendCommand("mydomain.url/doStuff");

Monday, 26 January 2015

Sqlite, the DB engine that could

sqlite3 is a great little DB engine for projects that need a small DB. It uses common SQL commands to store data in a local file. The file created by using the sqlite3 commands is the only database. Simple and affective it can be added to any script, or program with very little code.


BASH
echo "SELECT MAX(id)+1 FROM mytable;" | sqlite3 mydata.db 

PERL

use DBI;
$dbh = DBI->connect("dbi:SQLite:dbname=mydata.db", "", "", { sqlite_use_immediate_transaction => 1, RaiseError =>1 }) or die $DBI::errstr;
my $NextId = $dbh->selectall_arrayref("SELECT MAX(id)+1 FROM mytable;")->[0][0];

Friday, 23 January 2015

Perl data collation

When you need to gather data from many different sources and combine it in to one table of data there are a few ways to do it. The pr command can take data from many files and convert them to one table. Awk is a good choice also. Here is how I did it using Perl.

Here is the sample input data.
server1
09:53:01 94
09:53:02 96
09:53:03 95
server2
09:53:01 94
09:53:02 96
09:53:03 95
server3
09:53:01 94
09:53:02 96
09:53:03 95
server4
09:53:01 94
09:53:02 96
09:53:03 95
server5
09:53:01 94
09:53:02 96
09:53:03 95
server6
09:53:01 94
09:53:02 96
09:53:03 95
Here is the code. Save it as a Perl file and pipe your data into it.

#!/usr/bin/perl

while (<>) {
 @data = split(/\t/);
 if($data[0] =~ m/^\d/) {  
  $Times{$data[0]} = 1;
  chomp($data[1]);
  $Result{$Server}{$data[0]} = $data[1];
 } else {
  chomp($data[0]);
  $Servers{$data[0]} = 1;
  $Server = $data[0];
 }
}
printf "Time     \t";
foreach $S (keys %Servers) {
 printf "$S\t";
}
print "\n";
foreach $T (keys %Times) {
 print "$T\t";
 foreach $S (keys %Servers) {
  printf "$Result{$S}{$T}\t";
 }
 print "\n";
}

Here is your output.
Time      server3 server1 server2 server5 server4 server6 
09:53:02 96 96 96 96 96 96 
09:53:03 95 95 95 95 95 95 
09:53:01 94 94 94 94 94 94 

Thursday, 22 January 2015

Better shell history for power users.

One of the very first things I set up on any new OS install is my history. I like to keep a lot of it and I like to know when I ran the command. This is very easy to do with these two environment variables set in your profile. You can set them locally or globally.
[royce@royce-desktop ~]$ cat /etc/profile.d/history.sh 
export HISTSIZE=100000
export HISTTIMEFORMAT="[%F %T] "
[royce@royce-desktop ~]$ history |tail -n 2
74519  [2015-01-22 10:52:40] cat /etc/profile.d/history.sh 
74520  [2015-01-22 10:52:41] history |tail -n 2

Wednesday, 21 January 2015

The Power of AWK: svn log to RPM change history.

For many years I used awk and gawk to just do simple column parsing because it is so good at stripping out the white space. Recently I have begun to use awk to do more complex task. One of these is reading the subversion log and converting it to RPM change log history.

I am using this awk as part of my build system to automatically generate rpm.spec files as one step of my build system for my many projects.
The goal is to turn this
------------------------------------------------------------------------
r4 | royce | 2015-01-21 13:03:49 -0700 (Wed, 21 Jan 2015) | 1 line

New SVN project
------------------------------------------------------------------------
r3 | royce | 2015-01-21 10:13:03 -0700 (Wed, 21 Jan 2015) | 1 line


------------------------------------------------------------------------
r2 | royce | 2015-01-21 10:12:25 -0700 (Wed, 21 Jan 2015) | 1 line


------------------------------------------------------------------------
r1 | royce | 2015-01-21 10:02:31 -0700 (Wed, 21 Jan 2015) | 1 line

First build
------------------------------------------------------------------------


In to this
* Wed Jan 21 2015 Revision r4
- First build
- New SVN project



Below is the awk code.
Save it as the file SvnLog2SpecChangeLog.awk.
Then from your project directory run it as svn log | awk -f SvnLog2SpecChangeLog.awk

BEGIN {
   DI=1;
   LASTDATE="";
}

{
   # print "working on "$0
   if($1 == "------------------------------------------------------------------------") {
      nextrow=0
      # print "split row"
   } else {
      # print "text row"
      if(nextrow > 0) {
         if ($1 == "") {
            # print "Blank row"
            nextrow++;
         } else {
            DOCS[DI++]=$0;
         }
      }
      if(nextrow==0) {
         # print "Revison row also contains date"
         NEWREV=$1;
         NEWDATE=$5;
         nextrow++;
         if(LASTDATE != "") {
            # print "LASTDATE="LASTDATE;
            if((LASTDATE!=NEWDATE) && (DI > 1)) {
               DATECMD="date +\"%a %b %d %Y\" -d"LASTDATE
               DATECMD | getline DATEOUT;               
               printf("* %s Revision %s\n", DATEOUT, LASTREV);
               for (DK in DOCS) {
                  printf("- %s\n", DOCS[DK]);
               }
               printf "\n";
               delete DOCS;
               DI=1
               LASTDATE=NEWDATE;
               LASTREV=NEWREV;
            }
         } else {
            LASTDATE=NEWDATE;
            LASTREV=NEWREV;
         }
      }
   }
}

END {
   DATECMD="date +\"%a %b %d %Y\" -d"LASTDATE
   DATECMD | getline DATEOUT;               
   printf("* %s Revision %s\n", DATEOUT, LASTREV);
   for (DK in DOCS) {
      printf("- %s\n", DOCS[DK]);
   }
   printf "\n";
}