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

Last change on this file since 81 was 81, checked in by Dominic Hargreaves, 15 years ago

Licence my contributions under the MIT licence

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