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

Last change on this file since 134 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.