Thursday 18 November 2010

a neat(?) postgresql solution using row_number() and self joining

For the scheduling aspect of openmolar, a common task is to find where "freeslots" occur. In the original openmolar, I performed this logic using python code. For openmolar2 the database itself will perform this search.
Here's how.

let's make a trivial diary table
create table diary (
 ix serial primary key, 
 startTime time, 
 endTime time, 
 activity varchar(80));
leading to this table of data.
select * from diary;
ixstarttimeendtimeactivity
109:00:0009:30:00breakfast
209:30:0010:00:00jogging
313:00:0014:00:00lunch
410:00:0011:30:00meeting with joe
514:00:0018:00:00golfing at Royal Dornoch

so the problem is this... how can I query that table to discover my free time on that day?
(there is 90 minutes before lunch)
NOTE - the activities are NOT in order!

the answer (and I found this in the excellent "sql cookbook") involves getting a view of that table in the correct order, and then performing a join on adjacent rows.

so first, get the ordered view.
=> select * from diary order by starttime;
ix starttime endtime activity
1 09:00:00 09:30:00 breakfast
2 09:30:00 10:00:00 jogging
4 13:00:00 14:00:00 lunch
3 10:00:00 11:30:00 meeting with joe
5 14:00:00 18:00:00 golfing at Royal Dornoch


But this doesn't help... because there is no way to definatively refer to the "next" activity, to do this we need to replace ix with a generated rownumber. We will use the row_number() window function of postgres 8.4.

=> select * from (select row_number() over (order by starttime) as rownumber,
starttime, endtime, activity from diary) as ordered_diary;

rownumber starttime endtime activity
1 09:00:00 09:30:00 breakfast
2 09:30:00 10:00:00 jogging
3 10:00:00 11:30:00 meeting with joe
4 13:00:00 14:00:00 lunch
5 14:00:00 18:00:00 golfing at Royal Dornoch

no we can self join that result set on itself..
(adding columns from the next row to the current row)

=> select * from
(select row_number() over (order by starttime) as row_number, * from diary) as diary1,
(select row_number() over (order by starttime) as row_number, * from diary) as diary2
where diary2.row_number = diary1.row_number+1

row_number ix starttime endtime activity row_number ix starttime endtime activity
1 1 09:00:00 09:30:00 breakfast 2 2 09:30:00 10:00:00 jogging
2 2 09:30:00 10:00:00 jogging 3 4 10:00:00 11:30:00 meeting with joe
3 4 10:00:00 11:30:00 meeting with joe 4 3 13:00:00 14:00:00 lunch
4 3 13:00:00 14:00:00 lunch 5 5 14:00:00 18:00:00 golfing at Royal Dornoch


or more succinctly...
=> select diary1.activity as first_activity, diary1.endtime as finishes,
diary2.activity as next_activity, diary2.starttime as starts from
(select row_number() over (order by starttime) as row_number, * from diary) as diary1,
(select row_number() over (order by starttime) as row_number, * from diary) as diary2
where diary2.row_number = diary1.row_number+1

first_activity finishes next_activity starts
breakfast 09:30:00 jogging 09:30:00
jogging 10:00:00 meeting with joe 10:00:00
meeting with joe 11:30:00 lunch 13:00:00
lunch 14:00:00 golfing at Royal Dornoch 14:00:00

so we simply now have to add a check to see if those times differ

so here's the final query!

=> select diary1.endtime as freetime_start, diary2.starttime as freetime_end from
(select row_number() over (order by starttime) as row_number, endtime from diary) as diary1,
(select row_number() over (order by starttime) as row_number, starttime from diary) as diary2
where diary2.row_number = diary1.row_number+1
and diary1.endtime < diary2.starttime




freetime_start freetime_end
11:30:00 13:00:00

Friday 12 November 2010

Firesheep in Action

further to Yesterday's post on installing firesheep on 64-bit ubuntu .... I had a play with the firesheep plugin.

I disabled (temporarily) WPA on my home network, and started monitoring. I was able to hijack both my facebook and twitter sessions.

Thursday 11 November 2010

Firesheep.

Firesheep is a plugin for Firefox that is creating a lot of noise in the IT security community. It allows you to hijack sessions of other users on open wifi.

There is a windows/mac version of this plugin, but that is no use to me (and I will point out my intentions are NOT malicious, but to demonstrate to friends/colleagues the dangers of the interwebs).

thanks to information on this page I got it working on my 64-bit ubuntu 10.04(lucid) laptop.

here's what I did to get it working.
regards

Neil.

to install firesheep on lucid

1. get dependencies (your mileage may vary)

sudo apt-get install libhal-dev libtool autoconf xulrunner-dev libboost-dev libpcap-dev iw git

2. get the latest firesheep code from github

git clone git://github.com/mickflemm/firesheep.git

3. compile the firesheep.xpi "plugin"

cd firesheep
./autogen.sh
git submodule update --init
make

4. set up a monitor interface
sudo iw wlan0 interface add mon0 type monitor
sudo ifconfig mon0 up

5. Install the plugin into firefox.
Open Firefox, and from the menu choose "File", then open ~/firesheep/build/firesheep.xpi

restart firefox when asked

6. firesheep needs correct permissions to access your wifi card.

cd ~/.mozilla/firefox/7oyiuecg.default/extension/firesheep@codebutler.com/platform/Linux_x86_64-gcc3/

sudo ./firesheep-backend --fix-permissions

note- there WILL be subtle differences in this directory

7. Ready to go!

open firefox and click on
add-ons->firesheep->preferences->interface
then choose mon0 from the drop down list. (see screenshot below)

8. Enable the Firesheep Sidebar.

view->SideBar->firesheep;
(or ctrl-shift-s)

DONE!