source: trunk/npemap.org.uk/cgi/get-postcodes.fcgi @ 84

Last change on this file since 84 was 84, checked in by David Sheldon, 15 years ago

Reuse the marker DIVs in the hope of making it faster, and show a message whilst they load (an animated spinner didn't help as the speed limit is in the client).

  • Property svn:executable set to *
File size: 3.1 KB
Line 
1#!/usr/bin/perl
2#
3# Copyright (c) 2006 Dominic Hargreaves
4# See accompanying file "LICENCE" for licence details
5
6use strict;
7use warnings;
8
9use DBI;
10use CGI::Fast qw/:standard -debug/;
11
12use vars qw($dbname $dbhost $dbuser $dbpass);
13
14sub print_err;
15sub setup_dbh;
16
17# Read in database config
18my $config = 'npemap.conf';
19do $config or die "Can't read $config!\n";
20
21
22# Set up database handler to try and make sure it's ready for the first
23# request
24# No point in handling errors here since they'll get handled by the request
25# handler
26my $dbh;
27setup_dbh();
28
29
30my @fields = qw(mineasting minnorthing maxeasting maxnorthing);
31my $max_distance = 50000; # in metres
32
33my $cgi;
34# Process incoming requests
35REQUEST: while ($cgi = new CGI::Fast) {
36
37    # In case the database went away, make sure we have a connection
38    unless (setup_dbh()) {
39        print_internal_err('Error setting up database connection');
40        next REQUEST;
41    }
42
43    # Input validation
44    foreach my $field (@fields) {
45        unless (defined $cgi->param($field)) {
46            print_err ("Parameter '$field' missing");
47            next REQUEST;
48        }
49    }
50
51    # Are the Eastings in a valid range?
52    foreach (qw(mineasting maxeasting)) {
53        if (($cgi->param($_) > 700000) or
54            ($cgi->param($_) < 0)) {
55            print_err ("Parameter '$_' must be an integer between 0 and 700,000");
56            next REQUEST;
57        }
58    }
59
60    # Are the Northings in a valid range?
61    foreach (qw(minnorthing maxnorthing)) {
62        if (($cgi->param($_) > 1300000) or
63            ($cgi->param($_) < 0)) {
64            print_err("Parameter '$_' must be an integer between 0 and 1,300,000");
65            next REQUEST;
66        }
67    }
68   
69    # Is the box too big?
70    if (($cgi->param('maxeasting') - $cgi->param('mineasting') > $max_distance) or ($cgi->param('maxnorthing') - $cgi->param('minnorthing') > $max_distance)) {
71        print_err("The requested box is too large");
72        next REQUEST;
73    }
74
75    my $sth = $dbh->prepare("SELECT outward || ' ' || inward AS postcode, easting, northing,id FROM postcodes WHERE easting BETWEEN ? AND ? AND northing BETWEEN ? AND ?");
76   
77    if ($sth->execute($cgi->param('mineasting'), $cgi->param('maxeasting'), $cgi->param('minnorthing'), $cgi->param('maxnorthing'))) {
78        my $hr = $sth->fetchall_hashref('postcode');
79        print "Content-type: text/javascript\n\n";
80
81        foreach my $key (keys %$hr) {
82            my $hash = $$hr{$key};
83            print "addMarker('$$hash{postcode}', $$hash{easting}, $$hash{northing}, $$hash{id});\n";
84        }
85        print "completeMarkers();\n";
86    } else {
87        print_internal_err("Database error retrieving data");
88    }
89
90}
91
92# No more requests to serve, so tidy up
93$dbh->disconnect;
94
95# Helper routines
96sub print_err {
97    my $err = shift;
98    print header("text/plain", "400 $err");
99    print "Error: $err\n";
100}
101
102sub print_internal_err {
103    my $err = shift;
104    print header("text/plain", "500 $err");
105    print "Error: $err\n";
106}
107
108sub setup_dbh {
109    # $dbh is global
110    my $data_source = "dbi:Pg:dbname=$dbname";
111    $data_source .= ";host=$dbhost" if $dbhost;
112    return $dbh = DBI->connect_cached($data_source, $dbuser, $dbpass);
113}
Note: See TracBrowser for help on using the repository browser.