Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2011/11/07

More Details on Traveling Salesman

I have just received mail from a programmer in France who is interested in learning Perl and  asked about some of the constructs in my Traveling Salesman code, specifically asking about MyDB.pm and do_connect. That module and that function are about one thing: getting a DBI object without having to have my login and password and all that within the body of the program, so I can do things like paste it into my blog without worrying. Adapted, it looks like this:

  1. package MyDB ;  
  2. use strict;  
  3. use warnings;  
  4. use DBI;  
  5.   
  6. use Exporter qw(import);  
  7. our %EXPORT_TAGS = ('all' => [ qw(  
  8.                                    db_connect  
  9.                             ) ],  
  10.                     );  
  11. our @EXPORT_OK   = ( @{$EXPORT_TAGS{'all'}} );  
  12. our $VERSION = 0.0.1;  
  13. our %_DB = (  
  14.     default => {  
  15.         user       => 'YouDontGetThis',  
  16.         password   => 'YouDontGetThis',  
  17.         host       => 'YouDontGetThis',  
  18.         port       => '3306',  
  19.         database   => 'YouDontGetThis',  
  20.         },  
  21.     test => {  
  22.         user       => 'YouDontGetThis',  
  23.         password   => 'YouDontGetThis',  
  24.         host       => 'YouDontGetThis',  
  25.         port       => '3306',  
  26.         database   => 'YouDontGetThis',  
  27.         },  
  28.     );  
  29.   
  30. my $_db_params  = '';       # String of current database parameters.  
  31. my $_dbh;                   # Save the handle.  
  32.   
  33. sub db_connect {  
  34.     my ($param_ptr$attr_ptr) = @_;  
  35.   
  36.     # If database is already opened then check for a fast return.  
  37.   
  38.     if (defined $_dbh &&  
  39.         (!defined $param_ptr || $param_ptr eq ''))    { return $_dbh }  
  40.   
  41.     # Check for a different set of parameters to use via a the name (string)  
  42.     #   of the parameter (e.g., 'test').  
  43.   
  44.     my $which_db = 'default';  
  45.   
  46.     if (defined $param_ptr && ref($param_ptr) eq '' && $param_ptr ne '') {  
  47.         if (defined $_DB{$param_ptr})   { $which_db = $param_ptr }  
  48.         else { return; }  
  49.     }  
  50.   
  51.     # Get the base parameters ... copy and flatten from global array  
  52.   
  53.     my %params = ();  
  54.     my %attr   = ();  
  55.   
  56.     foreach (keys %{$_DB{$which_db}} ) {  
  57.         $params{$_} = $_DB{$which_db}{$_};  
  58.         }  
  59.   
  60.     # Add in extra parameters if given and if the database is not the default.  
  61.   
  62.     if (defined $param_ptr  
  63.         && ref($param_ptr) eq 'HASH'  
  64.         && (!defined $param_ptr->{database} ||  
  65.              $param_ptr->{database} ne 'default') ) {  
  66.   
  67.         foreach (keys %{$_DB{default}})  {  
  68.             if (defined $param_ptr->{$_}) { $params{$_} = $param_ptr->{$_} }  
  69.             }  
  70.         }  
  71.   
  72.     if (defined $attr_ptr && ref($attr_ptr) eq 'HASH') {  
  73.         foreach (keys %$attr_ptr)  { $attr{$_} = $attr_ptr->{$_} }  
  74.         }  
  75.   
  76.     # Now make up an order string of the parameters so that we can compare  
  77.     #   them to the old ones.  
  78.   
  79.     my $new_db_params = '';  
  80.     foreach (sort keys %params)  { $new_db_params .= $params{$_} };  
  81.   
  82.     # Can also do a quick return if params are same as old ones  
  83.   
  84.     if (defined $_dbh && $new_db_params eq $_db_params)  {  
  85.         return $_dbh;  
  86.         }  
  87.   
  88.     # At this point either the database has never been opened or  
  89.     #   new parameters are to be used. Close database and reopen.  
  90.   
  91.     $_db_params = $new_db_params;  
  92.   
  93.     if (defined $_dbh) { $_dbh->disconnect }    # no error check  
  94.   
  95.     my $source = "dbi:mysql:$params{database}:$params{host}:$params{port}";  
  96.   
  97.     $_dbh = DBI->connect($source$params{user},  
  98.                                $params{password}, \%attr);  
  99.   
  100.     return $_dbh;  
  101.   
  102.     } # End of db_connect  
  103.   
  104. 1;  

 For the particulars, I used something, I think WolframAlpha, to get the latitude and longitude of each capital, then looked into some geometry to calculate the distances. Perhaps I should include some database dumps here. for that info.

No comments:

Post a Comment