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

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

Better licence/copyright definition

  • 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 FROM postcodes WHERE easting BETWEEN ? AND ? AND northing BETWEEN ? AND ?");
76    if ($sth->execute($cgi->param('mineasting'), $cgi->param('maxeasting'), $cgi->param('minnorthing'), $cgi->param('maxnorthing'))) {
77        my $hr = $sth->fetchall_hashref('postcode');
78        print "Content-type: text/javascript\n\n";
79
80        foreach my $key (keys %$hr) {
81            my $hash = $$hr{$key};
82            print "addMarker('$$hash{postcode}', $$hash{easting}, $$hash{northing});\n";
83        }
84    } else {
85        print_internal_err("Database error retrieving data");
86    }
87
88}
89
90# No more requests to serve, so tidy up
91$dbh->disconnect;
92
93# Helper routines
94sub print_err($) {
95    my $err = shift;
96    print header("text/plain", "400 $err");
97    print "Error: $err\n";
98}
99
100sub print_internal_err($) {
101    my $err = shift;
102    print header("text/plain", "500 $err");
103    print "Error: $err\n";
104}
105
106sub setup_dbh {
107    # $dbh is global
108    my $data_source = "dbi:Pg:dbname=$dbname";
109    $data_source .= ";host=$dbhost" if $dbhost;
110    return $dbh = DBI->connect_cached($data_source, $dbuser, $dbpass);
111}
Note: See TracBrowser for help on using the repository browser.