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

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

Remove dependency on JSON and return error codes on error.

Fixes ticket:14

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