[Bast-commits] r3771 - in trunk/Locale-Object: . docs lib
lib/Locale lib/Locale/Object lib/Locale/Object/Currency t
castaway at dev.catalyst.perl.org
castaway at dev.catalyst.perl.org
Fri Sep 21 14:38:11 GMT 2007
Author: castaway
Date: 2007-09-21 14:38:11 +0100 (Fri, 21 Sep 2007)
New Revision: 3771
Added:
trunk/Locale-Object/Build.PL
trunk/Locale-Object/CHANGES
trunk/Locale-Object/INSTALL
trunk/Locale-Object/MANIFEST
trunk/Locale-Object/META.yml
trunk/Locale-Object/Makefile.PL
trunk/Locale-Object/README
trunk/Locale-Object/docs/
trunk/Locale-Object/docs/database.pod
trunk/Locale-Object/lib/
trunk/Locale-Object/lib/Locale/
trunk/Locale-Object/lib/Locale/Object.pm
trunk/Locale-Object/lib/Locale/Object/
trunk/Locale-Object/lib/Locale/Object/Continent.pm
trunk/Locale-Object/lib/Locale/Object/Country.pm
trunk/Locale-Object/lib/Locale/Object/Currency.pm
trunk/Locale-Object/lib/Locale/Object/Currency/
trunk/Locale-Object/lib/Locale/Object/Currency/Converter.pm
trunk/Locale-Object/lib/Locale/Object/DB.pm
trunk/Locale-Object/lib/Locale/Object/Language.pm
trunk/Locale-Object/lib/copy-for-test.PL
trunk/Locale-Object/locale.sql
trunk/Locale-Object/t/
trunk/Locale-Object/t/0_db.t
trunk/Locale-Object/t/1_country.t
trunk/Locale-Object/t/2_currency.t
trunk/Locale-Object/t/3_continent.t
trunk/Locale-Object/t/4_language.t
trunk/Locale-Object/t/5_object.t
trunk/Locale-Object/t/6_convert.t
trunk/Locale-Object/t/meta_pod.t
Log:
Committed initial revision (version 0.77)
Added: trunk/Locale-Object/Build.PL
===================================================================
--- trunk/Locale-Object/Build.PL (rev 0)
+++ trunk/Locale-Object/Build.PL 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,69 @@
+#!/usr/bin/perl
+
+use warnings;
+
+use FindBin qw( $Bin );
+use Module::Build;
+
+my $verbose = grep(/^--showsql$/, @ARGV);
+
+my $mb = Module::Build->new(
+ 'module_name' => 'Locale::Object',
+ 'license' => 'perl',
+ 'requires' => {
+ 'perl' => '5.6.0',
+ 'DateTime::TimeZone' => 0.4,
+ 'DateTime' => 0.3,
+ 'DBI' => 0,
+ 'DBD::SQLite' => 0,
+ 'Scalar::Util' => 1.10,
+ },
+ 'build_requires' => {
+ 'DBI' => 0,
+ 'DBD::SQLite' => 0,
+ 'Module::Build' => '0.21',
+ 'Test::More' => 0,
+ 'Test::Pod' => 0,
+ },
+);
+
+eval {
+ require DBI;
+ require DBD::SQLite;
+ 1;
+};
+
+if ($@) {
+ print "DBD::SQLite is required to run Build.PL. Please check your system configuration.\n";
+ exit 1;
+}
+
+my $db = "$Bin/lib/Locale/Object/locale.db";
+
+unlink($db);
+
+my $dbh;
+
+{
+ no warnings 'once'; # shut up about $DBI::errstr
+
+ $dbh = DBI->connect("dbi:SQLite:$db")
+ or die "Couldn't connect to $db: $DBI::errstr";
+}
+
+open (my $SQL, '<', "$Bin/locale.sql")
+ or die "Couldn't open SQL file ($Bin/locale.sql) to create database: $!";
+
+{
+ local $/ = ";\n";
+
+ while (<$SQL>) {
+ next unless $_;
+ print $_ if $verbose;
+ $dbh->do($_) or die $dbh->errstr;
+ }
+}
+
+close $SQL;
+
+$mb->create_build_script;
Added: trunk/Locale-Object/CHANGES
===================================================================
--- trunk/Locale-Object/CHANGES (rev 0)
+++ trunk/Locale-Object/CHANGES 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,160 @@
+2007-09-04: 0.77
+ - The Unicode edition. Added currency symbols for numerous currencies
+ that had previously been spelt out, like "slashed C" for the Costa Rican
+ colón, and "Tug" instead of the the Mongolian tögrög symbol. Improved
+ spelling/accentage of some currency names but most likely some more
+ work is needed. As usual, please let me know of ommissions/inaccuracies.
+ I did not include several symbols that do not currently seem to be
+ well supported, such as "U+20B2: GUARANI SIGN" and "U+17DB: KHMER
+ CURRENCY SYMBOL RIEL".
+
+2007-08-11: 0.76
+ - Jess Robinson and Matt S. Trout reported that using Getopt::Long in
+ Build.PL for the verbose option was eating up options meant to go to
+ Module::Build - fixed with a suggestion from Jos Boumans. Also renamed
+ the --verbose option to --showsql.
+ - DBD::SQLite wasn't in build_requires (Matt again).
+ - Pound symbol (£) was missing from the SQL (Jess again).
+ - Removed unnecessary use of warnings::register in most modules.
+ - Version number for Locale::Object::Country was incorrect.
+
+2007-01-06: 0.75
+ - More helpful Build.PL output. Will display the SQL being run if you use
+ the flag --verbose.
+ - Some minor updates to documentation and pruning of unneeded files.
+
+2006-06-28: 0.74
+ - Tom Insam at Fotango kindly patched Locale::Object to create the database
+ at build time from an SQL dump, instead of relying on a binary file
+ distributed with the modules which could go painfully out of date (see
+ note below). This smartly circumvents the issue I'd been having and means
+ we can to back to using DBD::SQLite. Thanks Tom.
+ - Dependencies updated to accomodate changes in DateTime.
+
+2006-06-26: 0.73X, the evil bearded release from the mirror universe
+
+ - PAUSE-- # Allows co-maintainer to upload a version that already exists!
+
+2005-08-12: 0.73
+ - Switched to using DBD::SQLite2 to access the database, on a tip from
+ Nathan McFarland. This is a workaround for the fact that SQLite's
+ internal format has changed. I've received several requests to release a
+ new version using the SQLite 3 format for the DB, and despite a
+ protracted period of trying very hard to convert it (see
+ http://use.perl.org/~hex/journal/24191 for the gory details) I still
+ haven't managed to get it working yet - hence this workaround.
+
+2004-04-24: 0.72
+ - Added a note to Language.pm about obsolete ISO 639 codes on a tip from
+ Robin Szemeti.
+ - Got rid of a warning the appearing when Object.pm tests were run.
+
+2004-03-31: 0.71
+ - Ask Bjoern Hansen provided a patch for a bug in using Antarctica as a
+ country and spotted that Congo was missing a continent listing in the
+ database. Thanks!
+
+2004-01-15: 0.7
+ - New sane() and make_sane() methods for Object.pm.
+ - New languages_official() method for Country.pm.
+ - Fixed a broken error message in Language.pm.
+ - Fixed list markup in database.pod.
+
+2004-01-06: 0.6
+ - New timezone() and all_timezones() methods for Country.pm that
+ interface with DateTime::TimeZone.
+ - Added new timezone table to db; removed old UTC offset stuff,
+ because DT::TZ deals with that.
+ - Moved Locale::Object::DB::Schemata to docs/database.pod as that
+ makes more sense.
+ - Added documentation to Object.pm.
+ - Added missing "Congo, the Democratic Republic of the" to db.
+ - Renumbered 00pod.t to 99pod.t.
+
+2003-12-30: 0.54_02
+ - Converter.pm only "carp"s now, not "croak"s, when required modules
+ are missing.
+ - Fixed broken version number for Scalar::Util in Build.PL.
+
+2003-12-29: 0.54_01
+ - Locale::Object itself now has functionality: creating compound
+ objects that can contain country, currency and language objects.
+ This is still incomplete, and the API is almost certainly going
+ to change.
+ - Altered tests and Converter.pm further after 0.53 test results
+ for more robustness. No longer has Finance::Currency::Convert::XE
+ and Finance::Currency::Convert::Yahoo as requirements.
+ - Language.pm's countries() will now return an array in array
+ context. Added missing documentation for method.
+ - Changed tests to use isa_ok().
+ - Removed an incorrect line of documentation from Language.pm.
+
+2003-12-22: 0.53
+ - Removed a chunk of old code that had got back into DB.pm
+ somehow and was causing warnings.
+ - Modified Converter.pm to try and deal with errors a little
+ better.
+ - Changed tests in 06converter.t to only indicate if conversions
+ don't succeed, rather than fail and break installation - if
+ they don't succeed, it may be a network problem rather than one
+ with the module. (Thanks to Jost Krieger and Barbie for test
+ results prompting this change.)
+
+2003-12-18: 0.52
+ - Made Continent.pm, Country.pm, Currency.pm and Language.pm
+ subclasses of Object.pm so they could share one new() method for
+ code efficiency. Also fixed them to have get/set methods for
+ internal attributes to improve robustness. Thanks to James Duncan
+ for both these suggestions.
+
+2003-12-18: 0.51
+ - Slight documentation patch.
+
+2003-12-17: 0.5
+ - Added new module: Locale::Object::Currency::Converter.
+
+2003-12-16: 0.41
+ - Added UTC offset data to the db.
+ - Added utc_offset_main() and utc_offsets_all() to Country.pm.
+ - Added a few more tests to bring subroutine coverage to 100%.
+
+2003-12-09: 0.4
+ - Added dialing_codes column to the the country table in the db
+ and populated it with international dialing codes.
+ - Added dialing_code method to Country.pm.
+ - Removed unused name_native, main_timezone and
+ uses_daylight_savings columns from the db, their
+ associated methods in Country.pm and listings in Schemata.pm.
+ - Added a couple of spots of missing POD markup to Schemata.pm.
+ - Updated two slightly out-of-date error messages in DB.pm.
+
+2003-12-01: 0.31
+ - Added Language.pm to MANIFEST where it should have been.
+
+2003-11-28: 0.3
+ - Added a new module: Language.pm.
+ - The database now contains a table of language-country mappings.
+ - New languages() method for Country.pm.
+ - New lookup_dual() method for DB.pm.
+ - Altered DB.pm's lookup() method - now returns a reference to an
+ array of hashes rather than an array. This should not change
+ again. Removed redundant lookup_all() method as a result.
+ - Continent.pm does now really actually give back an array.
+ - Added continent names to the database for some Pacific islands
+ that should have been listed as Oceania but weren't.
+ - Added currencies to the db that were missing for those same
+ islands.
+
+2003-11-25: 0.2
+ - Cleaned up the API a little - the countries() method in
+ Continent.pm and Currency.pm now gives an array back, instead
+ of a hash.
+
+2003-11-25: 0.11
+ - Fixed a bit of semi-finished and outdated documentation in DB.pm
+ that had crept past me.
+ - Added a little bit more documentation to copy-for-test.PL for
+ clarity.
+
+2003-11-24: 0.1
+ - Initial release.
Added: trunk/Locale-Object/INSTALL
===================================================================
--- trunk/Locale-Object/INSTALL (rev 0)
+++ trunk/Locale-Object/INSTALL 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,17 @@
+In order to install these modules, you need Module::Build. CPANPLUS.pm has
+had support for Module::Build since January of 2003; if you are currently
+using CPAN.pm, please consider upgrading to CPANPLUS. A Makefile.PL is
+included with this distribution, but it will ask if you want to install
+Module::Build, and do so with CPAN.pm if you so consent, and only then
+install the distribution.
+
+The install process is a standard Module::Build install:
+
+ perl Build.PL
+ ./Build
+ ./Build test
+ ./Build install
+
+To install into a custom lib path, use the install_path directive:
+
+ perl Build.PL install_path=lib=/path/to/my/lib
\ No newline at end of file
Added: trunk/Locale-Object/MANIFEST
===================================================================
--- trunk/Locale-Object/MANIFEST (rev 0)
+++ trunk/Locale-Object/MANIFEST 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,25 @@
+Build.PL
+CHANGES
+INSTALL
+locale.sql
+MANIFEST
+Makefile.PL
+META.yml
+README
+docs/database.pod
+lib/copy-for-test.PL
+lib/Locale/Object.pm
+lib/Locale/Object/Continent.pm
+lib/Locale/Object/Country.pm
+lib/Locale/Object/Currency.pm
+lib/Locale/Object/Currency/Converter.pm
+lib/Locale/Object/DB.pm
+lib/Locale/Object/Language.pm
+t/0_db.t
+t/1_country.t
+t/2_currency.t
+t/3_continent.t
+t/4_language.t
+t/5_object.t
+t/6_convert.t
+t/meta_pod.t
\ No newline at end of file
Added: trunk/Locale-Object/META.yml
===================================================================
--- trunk/Locale-Object/META.yml (rev 0)
+++ trunk/Locale-Object/META.yml 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,48 @@
+---
+name: Locale-Object
+version: 0.77
+author:
+ - 'Earle Martin <hex at cpan.org>'
+abstract: An object-oriented representation of locale information.
+license: perl
+resources:
+ license: http://dev.perl.org/licenses/
+requires:
+ DBD::SQLite: 0
+ DBI: 0
+ DateTime: 0.3
+ DateTime::TimeZone: 0.4
+ Scalar::Util: 1.1
+ perl: 5.6.0
+build_requires:
+ DBD::SQLite: 0
+ DBI: 0
+ Module::Build: 0.21
+ Test::More: 0
+ Test::Pod: 0
+provides:
+ Locale::Object:
+ file: lib/Locale/Object.pm
+ version: 0.77
+ Locale::Object::Continent:
+ file: lib/Locale/Object/Continent.pm
+ version: 0.77
+ Locale::Object::Country:
+ file: lib/Locale/Object/Country.pm
+ version: 0.77
+ Locale::Object::Currency:
+ file: lib/Locale/Object/Currency.pm
+ version: 0.77
+ Locale::Object::Currency::Converter:
+ file: lib/Locale/Object/Currency/Converter.pm
+ version: 0.77
+ Locale::Object::DB:
+ file: lib/Locale/Object/DB.pm
+ version: 0.77
+ Locale::Object::Language:
+ file: lib/Locale/Object/Language.pm
+ version: 0.77
+generated_by: Module::Build version 0.2805
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.2.html
+ version: 1.2
Added: trunk/Locale-Object/Makefile.PL
===================================================================
--- trunk/Locale-Object/Makefile.PL (rev 0)
+++ trunk/Locale-Object/Makefile.PL 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,28 @@
+
+ unless (eval "use Module::Build::Compat 0.02; 1" ) {
+ print "This module requires Module::Build to install itself.\n";
+
+ require ExtUtils::MakeMaker;
+ my $yn = ExtUtils::MakeMaker::prompt
+ (' Install Module::Build now from CPAN?', 'y');
+
+ unless ($yn =~ /^y/i) {
+ warn " *** Cannot install without Module::Build. Exiting ...\n";
+ exit 1;
+ }
+
+ require Cwd;
+ require File::Spec;
+ require CPAN;
+
+ # Save this 'cause CPAN will chdir all over the place.
+ my $cwd = Cwd::cwd();
+ my $makefile = File::Spec->rel2abs($0);
+
+ CPAN::Shell->install('Module::Build::Compat');
+
+ chdir $cwd or die "Cannot chdir() back to $cwd: $!";
+ exec $^X, $makefile, @ARGV; # Redo now that we have Module::Build
+ }
+ Module::Build::Compat->run_build_pl(args => \@ARGV);
+ Module::Build::Compat->write_makefile();
Added: trunk/Locale-Object/README
===================================================================
--- trunk/Locale-Object/README (rev 0)
+++ trunk/Locale-Object/README 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,51 @@
+NAME
+
+Locale::Object - OO locale information
+
+DESCRIPTION
+
+The Locale::Object group of modules attempts to provide locale-related
+information in an object-oriented fashion. The information is collated
+from several sources and provided in an accompanying DBD::SQLite database.
+
+At present, the modules are:
+
+* Locale::Object - make compound objects containing
+ country, currency & language objects
+* Locale::Object::Country - objects representing countries
+* Locale::Object::Continent - objects representing continents
+* Locale::Object::Currency - objects representing currencies
+* Locale::Object::Currency::Converter - convert between currencies
+* Locale::Object::DB - does db lookups for the modules
+* Locale::Object::Language - objects representing languages
+
+For more information, see the documentation for those modules. The database
+is documented in docs/database.pod.
+
+AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+* http://downlode.org/Code/Perl/
+
+CREDITS
+
+Original concept: Pierre Denis (PDENIS). I had much useful assistance from
+Pierre, Tom Insam (TOMI) - who contributed to my knowledge of DBI - and
+James Duncan (JDUNCAN). Most of the OO concepts involved I learnt from
+Damian Conway (DCONWAY)'s excellent book "Object Oriented Perl" (ISBN
+1-884777-79-1).
+
+COPYRIGHT
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is
+provided on an "as is" basis. No warranties of any kind are made, either
+expressed or implied, as to the accuracy and/or utility of any results
+obtained from its use. However, if you do find something wrong with the
+results, please let the author know. Thanks.
+
+SEE ALSO
+
+Locale::Codes, for simple conversions between names and ISO codes.
\ No newline at end of file
Added: trunk/Locale-Object/docs/database.pod
===================================================================
--- trunk/Locale-Object/docs/database.pod (rev 0)
+++ trunk/Locale-Object/docs/database.pod 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,150 @@
+=head1 NAME
+
+database.pod - documentation for the Locale::Object database
+
+=head2 THE DATABASE
+
+The database of locale information used by the L<Locale::Object> modules uses L<DBD::SQLite>, and contains several tables.
+
+=head3 the "country" table
+
+ CREATE TABLE country (
+ code_alpha2 char(2),
+ code_alpha3 char(3),
+ code_numeric smallint,
+ name char(100),
+ dialing_code smallint,
+ utc_offset_main char(5),
+ utc_offsets_all char(50),
+ PRIMARY KEY (code_alpha2)
+ );
+
+=over 4
+
+=item * C<code_alpha2> , C<code_alpha3>, C<code_numeric> and C<name> are data from ISO 3166 - see L<http://ftp.ics.uci.edu/pub/ietf/http/related/iso3166.txt>.
+
+=item * C<dialing_code> is an International Direct Dialing code - see L<http://kropla.com/dialcode.htm>.
+
+=item * C<utc_offset_main> is the time offset of the time zone of the country's capital from UTC, expressed decimally in hours. C<utc_offsets_all> is a comma-separated list of offsets for all time zones that the country falls across, listed from west to east. If there is only one value this will match C<utc_offset_main>.
+
+=back
+
+=head3 the "currency" table
+
+ CREATE TABLE currency (
+ country_code char(2),
+ name char(100),
+ code char(3),
+ code_numeric smallint,
+ symbol char(20),
+ subunit char(100),
+ subunit_amount smallint,
+ PRIMARY KEY (country_code)
+ );
+
+=over 4
+
+=item * C<country_code> contains ISO 3166 two-letter country codes, as in the previous table.
+
+=item * C<name> and C<code> contain ISO 4217 three-letter codes and names for world currencies - see L<http://fx.sauder.ubc.ca/iso4217.html>.
+
+=item * C<symbol>, C<subunit> and C<subunit_amount> contain currency symbols, subunits (such as cents) and the amounts of subunits that comprise a single currency unit (such as 100 [cents in a dollar]). This data was sourced from L<http://fx.sauder.ubc.ca/currency_table.html> and L<http://www.wazu.jp/gallery/Test_CurrencySymbols.html>.
+
+=back
+
+=head3 the "continent" table
+
+ CREATE TABLE continent (
+ country_code char(2),
+ name char(13),
+ PRIMARY KEY (country_code)
+ );
+
+=over 4
+
+=item *C<country_code> contains ISO 3166 two-letter codes again, and C<name> contains associated continent names (Africa, Asia, Europe, North America, Oceania and South America). Sourced from L<http://www.worldatlas.com/cntycont.htm>.
+
+=back
+
+=head3 the "language" table
+
+ CREATE TABLE language (
+ code_alpha2 char(2),
+ code_alpha3 char(3),
+ name char(100),
+ PRIMARY KEY (code_alpha2)
+ );
+
+=over 4
+
+=item * C<code_alpha2> contains 2-letter ISO 639-1 language codes. See L<http://www.loc.gov/standards/iso639-2/englangn.html>.
+
+=item * C<code_alpha3> contains 3-letter ISO 639-2. There two parts of ISO 639-2, B (for 'bibliographic') and T (for 'terminology'), which differ in 23 instances out of the full list of 464 codes. For simplicity, this module uses the ISO 639-2/T versions. For more information, see the URL above and also L<http://www.loc.gov/standards/iso639-2/develop.html>.
+
+=item * C<name> contains the standard names of languages in English as defined by ISO 639.
+
+=back
+
+=head3 the "language_mappings" table
+
+ CREATE TABLE language_mappings (
+ id char(4),
+ country char(2),
+ language char(3),
+ official boolean,
+ PRIMARY KEY (id)
+ );
+
+An example section of this table:
+
+ ID COUNTRY LANGUAGE OFFICIAL
+ at_0 at ger true
+ at_1 at slv false
+ at_2 at hrv false
+ at_3 at hun false
+
+What this tells us is that in Austria, four languages are spoken: German, Slovenian, Croatian (Hrvatska) and Hungarian, and that only German is an official language of Austria. The mappings are ranked in order of prevalence of language, official languages first, followed by non-official. Please note that this is approximate at best.
+
+My original source for the language-country mappings was L<http://www.infoplease.com/ipa/A0855611.html>. However, there is no clear origin for this list, which occurs in several places on the Web, and it required some serious rationalization before data was able to be usefully extracted for it.
+
+In addition to the preceding, the following sources were invaluable:
+
+=over 4
+
+=item * Nationmaster - L<http://www.nationmaster.com/>
+
+=item * Ethnologue - L<http://www.ethnologue.com/>
+
+=item * Wikipedia - L<http://en.wikipedia.org/>
+
+=back
+
+=head3 the "timezone" table
+
+ CREATE TABLE timezone (
+ country_code char(2),
+ timezone char(50),
+ is_default boolean
+ );
+
+An example section of this table:
+
+ COUNTRY_CODE TIMEZONE IS_DEFAULT
+ br America/Recife false
+ br America/Fortaleza false
+ br America/Belem false
+ br America/Noronha true
+
+=over 4
+
+=item * C<country_code> contains ISO 3166 two-letter country codes.
+
+=item * C<timezone> contains time zone names as defined in the Olson database. See L<http://www.twinsun.com/tz/tz-link.htm> for more than you ever wanted to know about this.
+
+=item * C<is_default> contains a boolean value indicating whether the time zone in question is default in the country. For countries with more than one time zone, a value of 'true' indicates the time zone covers the nation's capital.
+
+=back
+
+The data for this table was sourced from L<http://s.keim.free.fr/tz/tznames/>.
+
+=cut
Added: trunk/Locale-Object/lib/Locale/Object/Continent.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/Continent.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/Continent.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,224 @@
+package Locale::Object::Continent;
+
+use strict;
+use warnings;;
+use Carp qw(croak);
+
+use Locale::Object;
+use base qw( Locale::Object );
+
+use Locale::Object::Country;
+use Locale::Object::DB;
+
+our $VERSION = '0.77';
+
+my $db = Locale::Object::DB->new();
+
+# Initialize the hash where we'll keep our singleton continent objects.
+my $existing = {};
+
+# Yours is the hash, and everything that's in it.
+my %continents = map { $_ => undef }
+ ('Africa', 'Asia', 'Europe', 'North America', 'Oceania', 'South America');
+
+# Initialize the object.
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+ return unless %params;
+
+ # Two's a crowd.
+ my $num_params = keys %params;
+
+ croak "Error: No continent name specified for initialization." unless $params{name};
+ croak "Error: You can only specify a single continent name for initialization."
+ if $num_params > 1;
+
+ # Check for pre-existing objects. Return it if there is one.
+ my $continent = $self->exists($params{name});
+ return $continent if $continent;
+
+ # Initialize with a continent name.
+ my $name = $params{name};
+ $self->{_name} = $name;
+
+ # Register the new object.
+ $self->register();
+
+ # Return the object.
+ $self;
+}
+
+# Check if objects exist in the singletons hash.
+sub exists {
+ my $self = shift;
+
+ # Check existence of a object with the given parameter or with
+ # the name of the current object.
+ my $name = shift;
+
+ # Return the singleton object, if it exists.
+ $existing->{$name};
+}
+
+# Register the object as a singleton.
+sub register {
+ my $self = shift;
+
+ # Do nothing unless the object has a name.
+ my $name = $self->name or return;
+
+ # Put the current object into the singleton hash.
+ $existing->{$name} = $self;
+}
+
+sub name
+{
+ my $self = shift;
+ my $name = shift;
+
+ # If no arguments were given, return the name attribute of the current object.
+ # Otherwise, carry on and set one on the current object.
+ return $self->{_name} unless defined $name;
+
+ # Check we didn't fall off the edge of the world.
+ # http://www.maphist.nl/extra/herebedragons.html
+ croak "Error: unknown continent name given for initialization: '$name'" unless exists $continents{$name};
+
+ # Set the name.
+ $self->{_name} = $name;
+
+ # If a Continent object with that name exists, return it.
+ if (my $continent = $self->exists( $name ))
+ {
+ return $continent;
+ }
+ # Otherwise, register the current object as a singleton.
+ else
+ {
+ $self->register();
+ }
+
+ # Return the current object.
+ $self;
+}
+
+# Method for retrieving all countries in this continent.
+sub countries
+{
+ my $self = shift;
+
+ # No name, no countries.
+ return unless $self->{_name};
+
+ # Check for countries attribute. Set it if we don't have it.
+ _set_countries($self) unless $self->{_countries};
+
+ # Give an array if requested in array context, otherwise a reference.
+ return @{$self->{_countries}} if wantarray;
+ return $self->{_countries};
+}
+
+# Private method to set an attribute with an array of objects for all countries in this continent.
+sub _set_countries
+{
+ my $self = shift;
+
+ my (%country_codes, @countries);
+
+ # If it doesn't, find all countries in this continent.
+ my $result = $db->lookup(
+ table => 'continent',
+ result_column => 'country_code',
+ search_column => 'name',
+ value => $self->{'_name'}
+ );
+
+ # Create new country objects and put them into an array.
+ foreach my $place (@{$result})
+ {
+ my $where = $place->{'country_code'};
+
+ my $obj = Locale::Object::Country->new( code_alpha2 => $where );
+ push @countries, $obj;
+ }
+
+ # Set a reference to that array as an attribute.
+ $self->{'_countries'} = \@countries;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::Continent - continent information objects
+
+=head1 DESCRIPTION
+
+C<Locale::Object::Continent> allows you to create objects representing continents, that contain other objects representing the continent in question's countries.
+
+=head1 SYNOPSIS
+
+ my $asia = Locale::Object::Continent->new( name => 'Asia' );
+
+ my $name = $asia->name;
+ my @countries = $asia->countries;
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $asia = Locale::Object::Continent->new( name => 'Asia' );
+
+The C<new> method creates an object. It takes a single-item hash as an argument - the only valid options to it is 'name', which must be one of 'Africa', 'Asia', 'Europe', 'North America', 'Oceania' or 'South America'. Support for Antarctic territories is not currently provided.
+
+The objects created are singletons; if you try and create a continent object when one matching your specification already exists, C<new()> will return the original one.
+
+=head2 C<name()>
+
+ my $name = $asia->name;
+
+Retrieves the value of the continent object's name.
+
+=head2 C<countries()>
+
+ my @countries = $asia->countries;
+
+Returns an array of L<Locale::Object::Country> objects with their ISO 3166 alpha2 codes as keys (see L<Locale::Object::DB::Schemata> for more details on those) in array context, or a reference in scalar context. The objects have their own attribute methods, so you can do things like this:
+
+ foreach my $place (@countries)
+ {
+ print $place->name, "\n";
+ }
+
+Which will list you all the currencies used in that continent. See the documentation for L<Locale::Object::Country> for a listing of country attributes. Note that you can chain methods as well.
+
+ foreach my $place (@countries)
+ {
+ print $place->currency->name, "\n";
+ }
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty of any kind is made, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
Added: trunk/Locale-Object/lib/Locale/Object/Country.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/Country.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/Country.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,497 @@
+package Locale::Object::Country;
+
+use strict;
+use warnings;;
+use Carp;
+
+use Locale::Object;
+use base qw( Locale::Object );
+
+use Locale::Object::DB;
+use Locale::Object::Currency;
+use Locale::Object::Continent;
+use Locale::Object::Language;
+
+use DateTime::TimeZone;
+
+our $VERSION = '0.77';
+
+my $db = Locale::Object::DB->new();
+
+# Initialize the hash where we'll keep our continent objects.
+my $existing = {};
+
+
+# Initialize the object.
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+
+ # One parameter is allowed.
+ croak "Error: You must specify a single parameter for initialization."
+ unless scalar(keys %params) == 1;
+
+ # It's the only key in %params.
+ my $parameter = (keys %params)[0];
+
+ # Make a hash of valid parameters.
+ my %allowed_params = map { $_ => undef }
+ qw(code_alpha2 code_alpha3 code_numeric name);
+
+ # Go no further if the specified parameter wasn't one.
+ croak "Error: You can only specify a country name, alpha2 code, alpha3 code or numeric code for initialization." unless exists $allowed_params{$parameter};
+
+ # Get the value given for the parameter.
+ my $value = $params{$parameter};
+
+ # Make sure input matches style of values in the db.
+ if ($parameter eq 'name')
+ {
+ $value = ucfirst($value);
+ }
+ elsif ($parameter eq 'code_alpha2' or $parameter eq 'code_alpha3')
+ {
+ $value = lc($value);
+ }
+
+ # Look in the database for a match.
+ my $result = $db->lookup(
+ table => 'country',
+ result_column => '*',
+ search_column => $parameter,
+ value => $value
+ );
+
+ croak "Error: Unknown $parameter given for initialization: $value" unless $result;
+
+ if (defined @{$result}[0])
+ {
+ # Get the values from the result of our database query.
+ my $code_alpha2 = $result->[0]->{'code_alpha2'};
+ my $code_alpha3 = $result->[0]->{'code_alpha3'};
+ my $code_numeric = $result->[0]->{'code_numeric'};
+ my $name = $result->[0]->{'name'};
+ my $dialing_code = $result->[0]->{'dialing_code'};
+
+ $result = $db->lookup_dual(
+ table => 'timezone',
+ result_col => 'timezone',
+ col_1 => 'country_code',
+ val_1 => $code_alpha2,
+ col_2 => 'is_default',
+ val_2 => 'true'
+ );
+
+ my $timezone = $result->[0]->{timezone};
+
+ # Check for pre-existing objects. Return it if there is one.
+ my $country = $self->exists($code_alpha2);
+ return $country if $country;
+
+ # If not, make a new object.
+ _make_country($self, $code_alpha2, $code_alpha3, $code_numeric, $name, $dialing_code, $timezone);
+
+ # Register the new object.
+ $self->register();
+
+ # Return the object.
+ $self;
+ }
+ else
+ {
+ carp "Warning: No result found in country table for '$value' in $parameter.";
+ return;
+ }
+}
+
+# Check if objects exist.
+sub exists {
+ my $self = shift;
+
+ # Check existence of a object with the given parameter or with
+ # the alpha2 code of the current object.
+ my $code = shift;
+
+ # Return the singleton object, if it exists.
+ $existing->{$code};
+}
+
+# Register the object in our hash of existing objects.
+sub register {
+ my $self = shift;
+
+ # Do nothing unless the object exists.
+ my $code = $self->code_alpha2 or return;
+
+ # Put the current object into the singleton hash.
+ $existing->{$code} = $self;
+}
+
+sub _make_country
+{
+ my $self = shift;
+ my @attributes = @_;
+
+ # The first attribute we get is the alpha2 country code.
+ my $code = $attributes[0];
+
+ # The attributes we want to set.
+ my @attr_names = qw(code_alpha2 code_alpha3 code_numeric name dialing_code timezone);
+
+ # Initialize a loop counter.
+ my $counter = 0;
+
+ # For each of those attributes,
+ foreach my $current_attribute (@attr_names)
+ {
+ # set it on the object.
+ $self->$current_attribute( $attributes[$counter] );
+ $counter++;
+ }
+
+ # Check there's a continent row matching our current country.
+ my $result = $db->lookup(
+ table => 'continent',
+ result_column => '*',
+ search_column => 'country_code',
+ value => $code
+ );
+
+ croak "Error: no continent found in the database for country code $code." unless @{$result}[0];
+
+ my $continent = @{$result}[0]->{'name'};
+
+ # Make new continent and currency objects as attributes.
+ $self->{_continent} = Locale::Object::Continent->new( name => $continent );
+ $self->{_currency} = Locale::Object::Currency->new( country_code => $code );
+
+}
+
+# Method for retrieving all languages spoken in this country.
+sub languages
+{
+ my $self = shift;
+
+ # No name, no languages.
+ return unless $self->{_name};
+
+ # Check for languages attribute. Set it if we don't have it.
+ _set_languages($self) unless $self->{_languages};
+
+ # Give an array if requested in array context, otherwise a reference.
+ return @{$self->{_languages}} if wantarray;
+ return $self->{_languages};
+}
+
+# Method for retrieving the official language(s) of this country.
+sub languages_official
+{
+ my $self = shift;
+
+ # No name, no languages.
+ return unless $self->{_name};
+
+ # Check for languages attribute. Set it if we don't have it.
+ _set_languages($self) unless $self->{_languages};
+
+ my @official_languages;
+
+ foreach ($self->languages)
+ {
+ push (@official_languages, $_) if $_->official($self) eq 'true';
+ }
+
+ # Give an array if requested in array context, otherwise a reference.
+ return @official_languages if wantarray;
+ return \@official_languages;
+}
+
+# Private method to set an attribute with an array of objects for all languages spoken in this country.
+sub _set_languages
+{
+ my $self = shift;
+
+ my @languages;
+
+ # If it doesn't, find all countries in this continent and put them in a hash.
+ my $result = $db->lookup(
+ table => 'language_mappings',
+ result_column => 'language',
+ search_column => 'country',
+ value => $self->{'_code_alpha2'}
+ );
+
+ # Create new country objects and put them into an array.
+ foreach my $lang (@{$result})
+ {
+ my $lang_code = $lang->{'language'};
+
+ my $obj = Locale::Object::Language->new( code_alpha3 => $lang_code );
+ push @languages, $obj;
+ }
+
+ # Set a reference to that array as an attribute.
+ $self->{'_languages'} = \@languages;
+}
+
+# Small methods that return object attributes.
+# Will refactor these into an AUTOLOAD later.
+
+sub code_alpha2
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_alpha2} = shift;
+ return $self;
+ }
+
+ $self->{_code_alpha2};
+}
+
+sub code_alpha3
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_alpha3} = shift;
+ return $self;
+ }
+
+ $self->{_code_alpha3};
+}
+
+sub code_numeric
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_numeric} = shift;
+ return $self;
+ }
+
+ $self->{_code_numeric};
+}
+
+sub continent
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_continent} = shift;
+ return $self;
+ }
+
+ $self->{_continent};
+}
+
+sub currency
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_currency} = shift;
+ return $self;
+ }
+
+ $self->{_currency};
+}
+
+sub dialing_code
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_dialing_code} = shift;
+ return $self;
+ }
+
+ $self->{_dialing_code};
+}
+
+sub name
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_name} = shift;
+ return $self;
+ }
+
+ $self->{_name};
+}
+
+sub timezone
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ my $timezone = shift;
+ return $self unless $timezone;
+ $self->{_timezone} = DateTime::TimeZone->new( name => $timezone );
+
+ return $self;
+ }
+
+ $self->{_timezone};
+}
+
+sub all_timezones
+{
+ my $self = shift;
+
+ # Get the country alpha2 code.
+ my $code = $self->code_alpha2;
+
+ # If the all_timezones attribute exists, return it.
+ if ($self->{_all_timezones})
+ {
+ return @{$self->{_all_timezones}} if wantarray;
+ return $self->{_all_timezones};
+ }
+ # Otherwise, set it.
+ else
+ {
+ # Get all time zones for the country code.
+ my $results = $db->lookup(
+ table => 'timezone',
+ search_column => 'country_code',
+ result_column => '*',
+ value => $code
+ );
+ my @timezones;
+
+ foreach my $search_result (@{$results})
+ {
+ # Get the timezone from each result.
+ my $zone = $search_result->{timezone};
+
+ # Make a new object.
+ my $tz_object = DateTime::TimeZone->new( name => $zone );
+
+ # Stick it in an array.
+ push @timezones, $tz_object;
+ }
+
+ $self->{_all_timezones} = \@timezones;
+
+ return @{$self->{_all_timezones}} if wantarray;
+ return $self->{_all_timezones};
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::Country - country information objects
+
+=head1 DESCRIPTION
+
+C<Locale::Object::Country> allows you to create objects containing information about countries such as their ISO codes, currencies and so on.
+
+=head1 SYNOPSIS
+
+ use Locale::Object::Country;
+
+ my $country = Locale::Object::Country->new( code_alpha2 => 'af' );
+
+ my $name = $country->name; # 'Afghanistan'
+ my $code_alpha3 = $country->code_alpha3; # 'afg'
+ my $dialing_code = $country->dialing_code; # '93'
+
+ my $currency = $country->currency;
+ my $continent = $country->continent;
+
+ my @languages = $country->languages;
+ my @official = $country->languages_official;
+
+ my $timezone = $country->timezone;
+ my @allzones = @{$country->all_timezones};
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $country = Locale::Object::Country->new( code => 'af' );
+
+The C<new> method creates an object. It takes a single-item hash as an argument - valid options to pass are ISO 3166 values - 'code_alpha2', 'code_alpha3', 'code_numeric' and 'name'. See L<Locale::Object::DB::Schemata> for details on these.
+
+The objects created are singletons; if you try and create a country object when one matching your specification already exists, C<new()> will return the original one.
+
+=head2 C<code_alpha2(), code_alpha3(), code_numeric(), name(), dialing_code()>
+
+ my $name = $country->name;
+
+These methods retrieve the values of the attributes whose name they share in the object.
+
+=head2 C<currency(), continent()>
+
+These methods return L<Locale::Object::Currency> and L<Locale::Object::Continent> objects respectively. Both of those have their own attribute methods, so you can do things like this:
+
+ my $currency = $country->currency;
+ my $currency_name = $currency->name;
+
+See the documentation for those two modules for a listing of currency and continent attributes.
+
+Note: More attributes will be added in a future release; see L<Locale::Object::DB::Schemata> for a full listing of the contents of the database.
+
+=head2 C<languages(), languages_official()>
+
+ my @languages = $country->languages;
+
+C<languages()> returns an array of L<Locale::Object::Language> objects in array context, or a reference in scalar context. The objects have their own attribute methods, so you can do things like this:
+
+ foreach my $lang (@languages)
+ {
+ print $lang->name, "\n";
+ }
+
+C<languages_official()> does much the same thing, but only gives languages that are official in that country. Note: you can also use the C<official()> method of a L<Locale::Object::Language> object on a country object; this will return a boolean value describing whether the language is official in that country.
+
+=head2 C<timezone()>
+
+ my $timezone = $country->timezone;
+
+This method will return you a L<DateTime::TimeZone> object corresponding with the time zone in the capital of the country your object represents. See the documentation for that module to see what methods it provides; as a simple example:
+
+ my $timezone_name = $timezone->name;
+
+=head2 C<all_timezones()>
+
+ my @allzones = @{$country->all_timezones};
+
+This method will return an array or array reference, depending on context, of L<DateTime::TimeZone> objects for all time zones that occur in the country your object represents. In most cases this will be only one, and in some cases it will be quite a few (for example, the US, Canada, and Russian Federation).
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty of any kind is made, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
Added: trunk/Locale-Object/lib/Locale/Object/Currency/Converter.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/Currency/Converter.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/Currency/Converter.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,413 @@
+package Locale::Object::Currency::Converter;
+
+use strict;
+use warnings;;
+use Carp;
+
+use Scalar::Util qw(looks_like_number);
+
+our $VERSION = '0.77';
+
+my ($use_xe, $xe_error, $use_yahoo, $yahoo_error);
+
+# Check if we have the two modules that actually do the work of conversions.
+eval {
+ require Finance::Currency::Convert::XE;
+};
+
+if ($@)
+{
+ $use_xe = 0;
+ $xe_error = $@;
+}
+else
+{
+ $use_xe = 1;
+}
+
+eval {
+ require Finance::Currency::Convert::Yahoo;
+};
+
+if ($@)
+{
+ $use_yahoo = 0;
+ $yahoo_error = $@;
+}
+else
+{
+ $use_yahoo = 1;
+}
+
+
+sub new
+{
+ my $class = shift;
+ my %params = @_;
+
+ my $self = bless {}, $class;
+
+ # Initialize the new object or return an existing one.
+ $self->init(%params);
+}
+
+# Initialize the object.
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+
+ # Make a hash of valid parameters.
+ my %allowed_params = map { $_ => undef }
+ qw(service from to);
+
+ foreach my $key (keys %params)
+ {
+ # Go no further if the specified parameter wasn't one.
+ croak "Error: You can only specify a service to use and currencies to convert between for initialization." unless exists $allowed_params{$key};
+ }
+
+ # Set an attribute of the chosen currency conversion service.
+ if ($params{service})
+ {
+ croak "Error: Values for service can be 'XE' or 'Yahoo'; you said $params{service}." unless $params{service} =~ /^Yahoo$|^XE$/;
+
+ $self->{service} = $params{service};
+ }
+
+ # Set an attribute of the currency to convert from.
+ if ($params{from})
+ {
+ croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $params{from}->isa('Locale::Object::Currency');
+
+ $self->{from} = $params{from};
+ }
+
+ # Set an attribute of the currency to convert to.
+ if ($params{to})
+ {
+ croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $params{to}->isa('Locale::Object::Currency');
+
+ $self->{to} = $params{to};
+ }
+
+ # Return the object.
+ $self;
+}
+
+# Set currency service to be used.
+sub service
+{
+ my $self = shift;
+ my $service = shift;
+
+ # Be generous in what we accept.
+ $service = lc($service);
+
+ if ($service eq 'xe')
+ {
+ # Check that we can use Finance::Currency::Convert::XE.
+ if ($use_xe == 1)
+ {
+ return $self;
+ }
+ else
+ {
+ carp "WARNING: Cannot set service to XE: $xe_error";
+ }
+ }
+ elsif ($service eq 'yahoo')
+ {
+ # Check that we can use Finance::Currency::Convert::Yahoo.
+ if ($use_yahoo == 1)
+ {
+ return $self;
+ }
+ else
+ {
+ carp "WARNING: Cannot set service to Yahoo: $yahoo_error";
+ }
+ }
+ else
+ {
+ carp "ERROR: Values for service can be 'XE' or 'Yahoo' (case-insensitive); you said '$service'.";
+ }
+
+ $self->{service} = $service;
+}
+
+# Set currency to be converted from.
+sub from
+{
+ my $self = shift;
+ my $from = shift;
+
+ croak "Error: you can only use a Locale::Object::Currency object to convert from." unless $from->isa('Locale::Object::Currency');
+
+ $self->{from} = $from;
+}
+
+# Set currency to converted to.
+sub to
+{
+ my $self = shift;
+ my $to = shift;
+
+ croak "Error: you can only use a Locale::Object::Currency object to convert to." unless $to->isa('Locale::Object::Currency');
+
+ $self->{to} = $to;
+
+}
+
+# Do currency conversions.
+sub convert
+{
+ my $self = shift;
+ my $value = shift;
+
+ # Test if $value is numeric with Scalar::Util.
+ croak "Error: Argument '$value' to convert not numeric" unless looks_like_number($value);
+
+ croak "Error: No currency set to convert from" unless $self->{from};
+ croak "Error: No currency set to convert to" unless $self->{to};
+ croak "Error: No service specified for conversion" unless $self->{service};
+
+ my $result;
+
+ if ($self->{service} eq 'Yahoo')
+ {
+ $result = _yahoo($self, $value);
+ }
+ elsif ($self->{service} eq 'XE')
+ {
+ $result = _xe($self, $value);
+ }
+
+ $result;
+}
+
+# Internal method to do Yahoo! currency conversions.
+sub _yahoo
+{
+ my $self = shift;
+ my $value = shift;
+
+ # We're not in a talkative mood.
+ $Finance::Currency::Convert::Yahoo::CHAT = undef;
+
+ my $result;
+
+ eval {
+ $result = Finance::Currency::Convert::Yahoo::convert($value,$self->{from}->code,$self->{to}->code);
+ };
+
+ return "ERROR: $!" if $! ne '';
+
+ $result;
+}
+
+# Internal method to do XE currency conversions.
+sub _xe
+{
+ my $self = shift;
+ my $value = shift;
+
+ my $xe = Finance::Currency::Convert::XE->new() or croak "Error: Couldn't create Finance::Currency::Convert::XE object: $!";
+
+ my $result;
+
+ eval
+ {
+ $result = $xe->convert(
+ 'source' => $self->{from}->code,
+ 'target' => $self->{to}->code,
+ 'value' => $value
+ );
+ };
+
+ return "ERROR: $!" if $! ne '';
+
+ $result;
+}
+
+# Give the exchange rate of the currencies.
+sub rate
+{
+ my $self = shift;
+
+ # If there's no rate stored, set one.
+ $self->refresh unless $self->{_rate};
+
+ return $self->{_rate};
+}
+
+# Give the time that the rate was stored.
+sub timestamp
+{
+ my $self = shift;
+
+ if ($self->{_timestamp})
+ {
+ return $self->{_timestamp};
+ }
+ else
+ {
+ return undef;
+ }
+}
+
+# Update the exchange rate.
+sub refresh
+{
+ my $self = shift;
+
+ # Do a conversion to get the rate.
+ my $rate = $self->convert(1);
+
+ # Make a note of the rate and the time.
+ $self->{_rate} = $rate;
+ $self->{_timestamp} = time;
+}
+
+# Can you use Finance::Currency::Convert::XE?
+sub use_xe
+{
+ $use_xe;
+}
+
+# Can you use Finance::Currency::Convert::Yahoo?
+sub use_yahoo
+{
+ $use_yahoo;
+}
+
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::Currency::Converter - convert between currencies
+
+=head1 DESCRIPTION
+
+C<Locale::Object::Currency::Converter> allows you to convert between values of currencies represented by L<Locale::Object::Currency> objects.
+
+=head1 SYNOPSIS
+
+ use Locale::Object::Currency;
+ use Locale::Object::Currency::Converter;
+
+ my $usd = Locale::Object::Currency->new( code => 'USD' );
+ my $gbp = Locale::Object::Currency->new( code => 'GBP' );
+ my $eur = Locale::Object::Currency->new( code => 'EUR' );
+ my $jpy = Locale::Object::Currency->new( code => 'JPY' );
+
+ my $converter = Locale::Object::Currency::Converter->new(
+ from => $usd,
+ to => $gbp,
+ service => 'XE'
+ );
+
+ my $result = $converter->convert(5);
+ my $rate = $converter->rate;
+ my $timestamp = $converter->timestamp;
+
+ print $converter->use_xe;
+ print $converter->use_yahoo;
+
+ $converter->from($eur);
+ $converter->to($jpy);
+ $converter->service('Yahoo');
+
+ $converter->refresh;
+
+=head1 PREREQUISITES
+
+This module requires L<Finance::Currency::Convert::XE> and L<Finance::Currency::Convert::Yahoo>.
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $converter = Locale::Object::Currency::Converter->new();
+
+Creates a new converter object. With no arguments, creates a blank object. Possible arguments are C<from>, C<to> and C<service>, all or none of which may be given. C<from> and C<to> must be L<Locale::Object::Currency> objects. C<service> must be one of either 'XE' or 'Yahoo', to specify the conversion should be done by L<http://xe.com/ucc/> or L<http://finance.yahoo.com/> respectively.
+
+=head2 C<use_xe()>
+
+ print $converter->use_xe;
+
+Returns 1 or 0 depending on whether a C<use Finance::Currency::Convert::XE;> was successful. If 1, you can do conversions using the XE.com service.
+
+=head2 C<use_yahoo()>
+
+ print $converter->use_yahoo;
+
+Returns 1 or 0 depending on whether a C<use Finance::Currency::Convert::Yahoo;> was successful. If 1, you can do conversions using the finance.yahoo.com service.
+
+=head2 C<from()>
+
+ $converter->from($eur);
+
+Sets a currency to do conversions from. Takes a L<Locale::Object::Currency> object.
+
+=head2 C<to()>
+
+ $converter->to($jpy);
+
+Sets a currency to do conversions to. Takes a L<Locale::Object::Currency> object.
+
+=head2 C<service()>
+
+ $converter->service('Yahoo');
+
+Sets which currency conversion service to use. Depends on two other modules; see C<use_xe()> and C<use_yahoo()> above.
+
+=head2 C<convert()>
+
+ my $result = $converter->convert(5);
+
+Does the currency conversion. Takes a numeric argument representng the amount of the 'from' currency to convert into the 'to' currency, gives the result. Will croak if you didn't select a conversion service, 'from' and 'to' currency when you did C<new()> or afterwards with the associated methods (see above).
+
+=head2 C<rate()>
+
+ my $rate = $converter->rate;
+
+Returns the conversion rate between your 'from' currency and your 'to' currency, as of the time you last did a conversion. If you haven't done any conversions yet, will do one first (the result for converting 1 unit of a currency into another currency is the rate) and give you that.
+
+=head2 C<timestamp()>
+
+ my $timestamp = $converter->timestamp;
+
+Returns the L<time> timestamp of the last time the currency exchange rate was stored, either the last time you did a C<convert()> or a C<refresh()>.
+
+=head2 C<refresh()>
+
+ $converter->refresh;
+
+Will update the stored conversion rate and timestamp by doing another conversion. Doesn't return anything.
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty of any kind is made, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
+
Added: trunk/Locale-Object/lib/Locale/Object/Currency.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/Currency.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/Currency.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,354 @@
+package Locale::Object::Currency;
+
+use strict;
+use warnings;;
+use Carp;
+
+use Locale::Object;
+use base qw( Locale::Object );
+
+use Locale::Object::Country;
+use Locale::Object::DB;
+
+our $VERSION = '0.77';
+
+my $db = Locale::Object::DB->new();
+
+# Initialize the hash where we'll keep our singleton currency objects.
+my $existing = {};
+
+my $class;
+
+# Initialize the object.
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+
+ # One parameter is allowed.
+ croak "Error: You must specify a single parameter for initialization."
+ unless scalar(keys %params) == 1;
+
+ # It's the only key in %params.
+ my $parameter = (keys %params)[0];
+
+ # Make a hash of valid parameters.
+ my %allowed_params = map { $_ => undef }
+ qw(country_code code code_numeric);
+
+ # Go no further if the specified parameter wasn't one.
+ croak "Error: You can only specify a country code, currency code or numeric code for initialization." unless exists $allowed_params{$parameter};
+
+ # Get the value given for the parameter.
+ my $value = $params{$parameter};
+
+ # Make sure input matches style of values in the db.
+ if ($parameter eq 'country_code')
+ {
+ $value = lc($value);
+ }
+ elsif ($parameter eq 'code')
+ {
+ $value = uc($value);
+ }
+
+ # Look in the database for a match.
+ my $result = $db->lookup(
+ table => 'currency',
+ result_column => '*',
+ search_column => $parameter,
+ value => $value
+ );
+
+ croak "Error: Unknown $parameter given for initialization: $value" unless $result;
+
+ if (defined @{$result}[0])
+ {
+ # Set values from the results of our query.
+ my $name = @{$result}[0]->{'name'};
+ my $code = @{$result}[0]->{'code'};
+ my $code_numeric = @{$result}[0]->{'code_numeric'};
+ my $symbol = @{$result}[0]->{'symbol'};
+ my $subunit = @{$result}[0]->{'subunit'};
+ my $subunit_amount = @{$result}[0]->{'subunit_amount'};
+
+ # Check for pre-existing objects. Return it if there is one.
+ my $currency = $self->exists($code);
+ return $currency if $currency;
+
+ # If not, make a new object.
+ _make_currency($self, $name, $code, $code_numeric, $symbol, $subunit, $subunit_amount);
+
+ # Register the new object.
+ $self->register();
+
+ # Return the object.
+ $self;
+ }
+ else
+ {
+ carp "Warning: No result found in currency table for '$value' in $parameter.";
+ return;
+ }
+}
+
+# Check if objects exist.
+sub exists {
+ my $self = shift;
+
+ # Check existence of a object with the given parameter or with
+ # the code of the current object.
+ my $code = shift || $self->code;
+
+ # Return the singleton object, if it exists.
+ $existing->{$code};
+}
+
+# Register the object in our hash of existing objects.
+sub register {
+ my $self = shift;
+
+ # Do nothing unless the object exists.
+ my $code = $self->code or return;
+
+ # Put the current object into the singleton hash.
+ $existing->{$code} = $self;
+}
+
+sub _make_currency
+{
+ my $self = shift;
+ my @attributes = @_;
+
+ # The third attribute we get is the currency code.
+ my $currency_code = $attributes[0];
+
+ # The attributes we want to set.
+ my @attr_names = qw(name code code_numeric symbol subunit subunit_amount);
+
+ # Initialize a loop counter.
+ my $counter = 0;
+
+ foreach my $current_attribute (@attr_names)
+ {
+ # Set the attributes of the entry for this currency code in the singleton hash.
+ $self->$current_attribute( $attributes[$counter] );
+
+ $counter++;
+ }
+
+}
+
+# Method for retrieving all countries using this currency.
+sub countries
+{
+ my $self = shift;
+
+ # No name, no countries.
+ return unless $self->{_name};
+
+ # Check for countries attribute. Set it if we don't have it.
+ _set_countries($self) unless $self->{_countries};
+
+ # Give an array if requested in array context, otherwise a reference.
+ return @{$self->{_countries}} if wantarray;
+ return $self->{_countries};
+}
+
+# Private method to set an attribute with a hash of objects for all countries using this currency.
+sub _set_countries
+{
+ my $self = shift;
+
+ my $code = $self->{_code};
+
+ # If it doesn't, find all countries using this currency and put them in a hash.
+ my (%country_codes, @countries);
+
+ my $result = $db->lookup(
+ table => "currency",
+ result_column => "country_code",
+ search_column => "code",
+ value => $existing->{$code}->{'_code'}
+ );
+
+ # Create new country objects and put them into an array.
+ foreach my $place (@{$result})
+ {
+ my $where = $place->{'country_code'};
+
+ my $obj = Locale::Object::Country->new( code_alpha2 => $where );
+ push @countries, $obj;
+ }
+
+ # Set a reference to that array as an attribute.
+ $self->{'_countries'} = \@countries;
+}
+
+# Get/set attributes.
+
+sub code
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code} = shift;
+ return $self;
+ }
+
+ $self->{_code};
+}
+
+sub name
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_name} = shift;
+ return $self;
+ }
+
+ $self->{_name};
+}
+
+sub code_numeric
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_numeric} = shift;
+ return $self;
+ }
+
+ $self->{_code_numeric};
+}
+
+sub symbol
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_symbol} = shift;
+ return $self;
+ }
+
+ $self->{_symbol};
+}
+
+sub subunit
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_subunit} = shift;
+ return $self;
+ }
+
+ $self->{_subunit};
+}
+
+sub subunit_amount
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_subunit_amount} = shift;
+ return $self;
+ }
+
+ $self->{_subunit_amount};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::Currency - currency information objects
+
+=head1 DESCRIPTION
+
+C<Locale::Object::Country> allows you to create objects containing information about countries such as their ISO codes, currencies and so on.
+
+=head1 SYNOPSIS
+
+ use Locale::Object::Currency;
+
+ my $usd = Locale::Object::Currency->new( country_code => 'us' );
+
+ my $name = $usd->name;
+ my $code = $usd->code;
+ my $code_numeric = $usd->code_numeric;
+ my $symbol = $usd->symbol;
+ my $subunit = $usd->subunit;
+ my $subunit_amount = $usd->subunit_amount;
+
+ my @countries = $usd->countries;
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $usd = Locale::Object::Currency->new( country_code => 'us' );
+
+The C<new> method creates an object. It takes a single-item hash as an argument - valid options to pass are ISO 3166 values - 'code' and 'code_numeric'; also 'country_code', which is an alpha2 country code (see L<Locale::Object::DB::Schemata> for details on these). If you give a country code, a currency object will be created representing the currency of the country you specified.
+
+The objects created are singletons; if you try and create a currency object when one matching your specification already exists, C<new()> will return the original one.
+
+=head2 C<name(), code(), code_numeric(), symbol(), subunit(), subunit_amount()>
+
+ my $name = $country->name;
+
+These methods retrieve the values of the attributes in the object whose name they share.
+
+=head2 C<countries()>
+
+ my @countries = $usd->countries;
+
+Returns an array (in array context, otherwise a reference) of L<Locale::Object::Country> objects with their ISO 3166 alpha2 codes as keys (see L<Locale::Object::DB::Schemata> for more details on those) for all countries using this currency in array context, or a reference in scalar context. The objects have their own attribute methods, so you can do things like this for example:
+
+ foreach my $place (@countries)
+ {
+ print $place->name, "\n";
+ }
+
+Which will list you all the countries that use in that currency. See the documentation for L<Locale::Object::Country> for a listing of country attributes. Note that you can chain methods as well.
+
+ foreach my $place (@countries)
+ {
+ print $place->continent->name, "\n";
+ }
+
+=head1 KNOWN BUGS
+
+The database of currency information is not perfect by a long stretch. If you find mistakes or missing information, please send them to the author.
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty of any kind is made, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
+
Added: trunk/Locale-Object/lib/Locale/Object/DB.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/DB.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/DB.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,232 @@
+package Locale::Object::DB;
+
+use strict;
+use warnings;;
+use Carp qw(croak);
+
+use DBI;
+use File::Spec;
+
+our $VERSION = '0.77';
+
+# The database should be in the same directory as this file. Get the location.
+my (undef, $path) = File::Spec->splitpath(__FILE__);
+my $db = $path . 'locale.db';
+
+# Check it's a binary file in the right location.
+croak "FATAL ERROR: The Locale::Object database was not in '$path', where I expected it. Please check your installation." unless -B $db;
+
+# Make a new object.
+sub new
+{
+ my $class = shift;
+ my $self = bless {} => ref($class) || $class;
+
+ return $self;
+}
+
+# Connect to our database.
+my $dbh = DBI->connect("dbi:SQLite:dbname=$db", "", "",
+{
+ PrintError => 1, RaiseError => 1, AutoCommit => 1
+} ) or croak DBI::errstr;
+
+
+# Method to return all values of 'result_column' in 'table' in rows that
+# have 'value' in 'search_column'.
+
+sub lookup
+{
+ my ($self, %params) = @_;
+
+ # There are four required parameters to this method.
+ my @required = qw(table result_column search_column value);
+
+ # Croak if any of them are missing.
+ for (0..$#required)
+ {
+ croak "Error: could not do lookup: no '$required[$_]' specified." unless defined($params{$required[$_]});
+ }
+
+ # Validate parameters.
+ _check_search_params($params{table}, $params{result_column}, $params{search_column});
+
+ # Prepare the SQL statement.
+ my $sth = $dbh->prepare(
+ "SELECT $params{result_column} from $params{table} WHERE $params{search_column}=?"
+ ) or croak "Error: Couldn't prepare SQL statement: " . DBI::errstr;
+
+ # Execute it.
+ $sth->execute($params{value}) or croak "Error: Couldn't execute SQL statement: " . DBI::errstr;
+
+ # Return a reference to an array of hashes.
+ return $sth->fetchall_arrayref({});
+}
+
+# Get a value for a cell in a row which matches 2 columns and their values specified.
+sub lookup_dual
+{
+ my ($self, %params) = @_;
+
+ # Required parameters for this method.
+ my @required = qw(table result_col col_1 val_1 col_2 val_2);
+
+ # Croak if any of them are missing.
+ for (0..$#required)
+ {
+ croak "Error: could not do lookup_dual: no '$required[$_]' specified." unless defined($params{$required[$_]});
+ }
+
+ # Validate parameters.
+ _check_search_params($params{table}, $params{result_col}, $params{col_1}, $params{val_1}, $params{col_2}, $params{val_2});
+
+ # Prepare the SQL statement.
+ my $sth = $dbh->prepare(
+ "SELECT $params{result_col} from $params{table} WHERE $params{col_1}=? AND $params{col_2}=?"
+ ) or croak "Error: Couldn't prepare SQL statement: " . DBI::errstr;
+
+ # Execute it.
+ $sth->execute($params{val_1}, $params{val_2})
+ or croak "Error: Couldn't execute SQL statement: " . DBI::errstr;
+
+ # Return a reference to an array of hashes.
+ return $sth->fetchall_arrayref({});
+}
+
+
+# Make a hash of allowed table names for searches.
+my %allowed_tables = map { $_ => 1 }
+ qw(continent country currency language language_mappings timezone);
+
+# Make a hash of allowed column names for searches.
+my %allowed_columns = map { $_ => 1 }
+ qw(country_code name name_native primary_language code code_numeric symbol subunit
+ subunit_amount code_alpha2 code_alpha3 id country language official timezone is_default *);
+
+# Sub for sanity check on search parameters. Does nothing except croak if an error is encountered.
+sub _check_search_params
+{
+ my ($table, $result_column, $search_column) = @_;
+
+ # You can only specify a valid table name.
+ croak "Error: $table is not a valid table."
+ unless $allowed_tables{$table};
+
+ # Check parameters.
+ if ($result_column)
+ {
+ # You can only specify a valid column name.
+ croak "Error: $result_column is not a valid result column."
+ unless $allowed_columns{$result_column};
+
+ croak "Error: $search_column is not a valid search column."
+ unless $allowed_columns{$search_column};
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::DB - do database lookups for Locale::Object modules
+
+=head1 DESCRIPTION
+
+This module provides common functionality for the Locale::Object modules by doing lookups in the database that comes with them (which uses L<DBD::SQLite>).
+
+=head1 SYNOPSIS
+
+ use Locale::Object::DB;
+
+ my $db = Locale::Object::DB->new();
+
+ my $table = 'country';
+ my $what = 'name';
+ my $value = 'Afghanistan';
+
+ my @results = $db->lookup($table, $what, $value);
+
+ my %countries;
+
+ $table = 'continent';
+ my $result_column = 'country_code';
+
+ my $results = $db->lookup(
+ table => $table,
+ result_column => $result_column,
+ search_column => $what,
+ value => $value
+ );
+
+ foreach my $item (@{$results})
+ {
+ print $item->{$result_column};
+ }
+
+ $result = $db->lookup_dual(
+ table => $table,
+ result_col => $result_column,
+ col_1 => $first_search_column,
+ val_1 => $first_search_value,
+ col_2 => $second_search_column,
+ val_2 => $second_search_value
+ );
+
+=head1 METHODS
+
+=head2 C<lookup()>
+
+ $db->lookup(
+ table => $table,
+ result_column => $result_column,
+ search_column => $search_column,
+ value => $value
+ );
+
+C<lookup> will return a reference to an anonymous array of hashes. The hashes will contain the results for a query of the database for cells in $result_column in $table that are in a row that has $value in $search_column. Use '*' as a value for result_column if you want to retrieve whole rows.
+
+For information on what db tables are available and where the data came from, see C<docs/database.pod>.
+
+IMPORTANT: The way of using this method has changed as of version 0.2, and in addition it supersedes the place formerly taken by C<lookup_all()>. Apologies for any inconvenience.
+
+=head2 C<lookup_dual()>
+
+ my $result = $db->lookup_dual(
+ table => $table,
+ result_col => $result_column,
+ col_1 => $first_search_column,
+ val_1 => $first_search_value,
+ col_2 => $second_search_column,
+ val_2 => $second_search_value
+ );
+
+C<lookup_dual> will return a reference to an anonymous array of hashes. The hashes will contain the results for a query of the database for cells in C<$result_column> in C<$table> that are in a row that has two specified values in two specified columns. Use '*' as a value for C<$result_column> if you want to retrieve whole rows.
+
+=head1 NOTES
+
+The database file itself is named C<locale.db> and must reside in the same directory as this module. If it's not present, the module will croak with a fatal error.
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.reserved. L<http://purl.org/net/earlemartin/>
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty is made of any kind, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
+
Added: trunk/Locale-Object/lib/Locale/Object/Language.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object/Language.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object/Language.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,356 @@
+package Locale::Object::Language;
+
+use strict;
+use warnings;;
+use Carp;
+
+use Locale::Object;
+use base qw( Locale::Object );
+
+use Locale::Object::Country;
+use Locale::Object::DB;
+
+our $VERSION = '0.77';
+
+my $db = Locale::Object::DB->new();
+
+# Initialize the hash where we'll keep our singleton currency objects.
+my $existing = {};
+
+my $class;
+
+# Initialize the object.
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+
+ # One parameter is allowed.
+ croak "Error: You must specify a single parameter for initialization."
+ unless scalar(keys %params) == 1;
+
+ # It's the only key in %params.
+ my $parameter = (keys %params)[0];
+
+ # Make a hash of valid parameters.
+ my %allowed_params = map { $_ => undef }
+ qw( code_alpha2 code_alpha3 name );
+
+ # Go no further if the specified parameter wasn't one.
+ croak "Error: You can only specify an alpha2 or alpha3 code or language name for initialization." unless exists $allowed_params{$parameter};
+
+ # Get the value given for the parameter.
+ my $value = $params{$parameter};
+
+ # Make sure input matches style of values in the db.
+ if ($parameter eq 'name')
+ {
+ $value = ucfirst($value);
+ }
+ elsif ($parameter eq 'code_alpha2' or $parameter eq 'code_alpha3')
+ {
+ $value = lc($value);
+ }
+
+ # Look in the database for a match.
+ my $result = $db->lookup(
+ table => 'language',
+ result_column => '*',
+ search_column => $parameter,
+ value => $value
+ );
+
+ croak "Error: Unknown $parameter given for initialization: $value" unless $result;
+
+ if (defined @{$result}[0])
+ {
+ # Get values from our query.
+ my $code_alpha2 = @{$result}[0]->{'code_alpha2'};
+ my $code_alpha3 = @{$result}[0]->{'code_alpha3'};
+ my $name = @{$result}[0]->{'name'};
+
+ # Check for pre-existing objects. Return it if there is one.
+ my $enguage = $self->exists($code_alpha3);
+ return $enguage if $enguage;
+
+ # If not, make a new object.
+ _make_language($self, $code_alpha2, $code_alpha3, $name);
+
+ # Register the new object.
+ $self->register();
+
+ # Return the object.
+ $self;
+ }
+ else
+ {
+ carp "Warning: No result found in language table for '$value' in $parameter.";
+ return;
+ }
+
+}
+
+# Check if objects exist.
+sub exists {
+ my $self = shift;
+
+ # Check existence of a object with the given parameter or with
+ # the code of the current object.
+ my $code_alpha3 = shift || $self->code_alpha3;
+
+ # Return the singleton object, if it exists.
+ $existing->{$code_alpha3};
+}
+
+# Register the object in our hash of existing objects.
+sub register {
+ my $self = shift;
+
+ # Do nothing unless the object exists.
+ my $code_alpha3 = $self->code_alpha3 or return;
+
+ # Put the current object into the singleton hash.
+ $existing->{$code_alpha3} = $self;
+}
+
+sub _make_language
+{
+ my $self = shift;
+ my @attributes = @_;
+
+ # The second attribute we get is the alpha3 language code.
+ my $code = $attributes[1];
+
+ # The attributes we want to set.
+ my @attr_names = qw(code_alpha2 code_alpha3 name);
+
+ # Initialize a loop counter.
+ my $counter = 0;
+
+ foreach my $current_attribute (@attr_names)
+ {
+ # Set the attributes of the entry for this currency code in the singleton hash.
+ $self->$current_attribute( $attributes[$counter] );
+
+ $counter++;
+ }
+
+}
+
+# Method for retrieving all countries using this language
+sub countries
+{
+ my $self = shift;
+
+ # Check for countries attribute. Set it if we don't have it.
+ _set_countries($self) if $self->{_name};
+
+ # Give an array if requested in array context, otherwise a reference.
+ return @{$self->{_countries}} if wantarray;
+ return $self->{_countries};
+}
+
+# Private method to set an attribute with a hash of objects for all countries using this currency.
+sub _set_countries
+{
+ my $self = shift;
+ my $code = $self->{_code_alpha3};
+
+ # Do nothing if the list already exists.
+ return if $existing->{$code}->{'_countries'};
+
+ # If it doesn't, find all countries using this currency and put them in a hash.
+ my @countries;
+
+ my $result = $db->lookup(
+ table => 'language_mappings',
+ result_column => 'country',
+ search_column => 'language',
+ value => $code
+ );
+
+ # Create new country objects and put them into an array.
+ foreach my $where (@{$result})
+ {
+ my $country_code = $where->{'country'};
+ my $obj = Locale::Object::Country->new( code_alpha2 => $country_code );
+ push @countries, $obj;
+ }
+
+ # Set a reference to that array as an attribute.
+ $self->{'_countries'} = \@countries;
+}
+
+# Get/set attributes.
+
+sub name
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_name} = shift;
+ return $self;
+ }
+
+ $self->{_name};
+}
+
+sub code_alpha2
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_alpha2} = shift;
+ return $self;
+ }
+
+ $self->{_code_alpha2};
+}
+
+sub code_alpha3
+{
+ my $self = shift;
+
+ if (@_)
+ {
+ $self->{_code_alpha3} = shift;
+ return $self;
+ }
+
+ $self->{_code_alpha3};
+}
+
+sub official
+{
+ my $self = shift;
+ my $where = shift;
+ my $selected = $self->code_alpha3;
+
+ croak "Error: you can only pass official() a Locale::Object::Country object." unless $where->isa('Locale::Object::Country');
+
+ my $country = $where->code_alpha2;
+
+ my $count = 0;
+
+ # For each language used in the country...
+
+ my @langs = ($where->languages);
+
+ my %used_langs = map { $_->code_alpha3 => $_ } @langs;
+
+ croak qq{ERROR: Language "$selected" is not used in } . $where->name . '.' unless exists $used_langs{$selected};
+
+ my $result = $db->lookup_dual(
+ table => 'language_mappings',
+ result_col => 'official',
+ col_1 => 'country',
+ val_1 => $country,
+ col_2 => 'language',
+ val_2 => $selected
+ );
+
+ return @{$result}[0]->{'official'};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object::Language - language information objects
+
+=head1 DESCRIPTION
+
+C<Locale::Object::Language> allows you to create objects containing information about languages such as their ISO codes, the countries they're used in and so on.
+
+=head1 SYNOPSIS
+
+ use Locale::Object::Language;
+
+ my $eng = Locale::Object::Language->new( code_alpha3 => 'eng' );
+
+ my $name = $eng->name;
+ my $code_alpha2 = $eng->code_alpha2;
+ my $code_alpha3 = $eng->code_alpha3;
+
+ my @countries = $eng->countries;
+
+ my $gb = Locale::Object::Country->new( code_alpha2 => 'gb' );
+
+ print $eng->official($gb);
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $eng = Locale::Object::Language->new( code_alpha3 => 'eng' );
+
+The C<new> method creates an object. It takes a single-item hash as an argument - valid options to pass are ISO 3166 values - 'code_alpha2', 'code_alpha3' and 'name' (see L<Locale::Object::DB::Schemata> for details on these).
+
+The objects created are singletons; if you try and create a currency object when one matching your specification already exists, C<new()> will return the original one.
+
+=head2 C<name(), code_alpha2(), code_alpha3()>
+
+ my $name = $country->name;
+
+These methods retrieve the values of the attributes in the object whose name they share.
+
+=head2 C<countries()>
+
+ my @countries = $eng->countries;
+
+Returns an array (in array context, otherwise a reference) of L<Locale::Object::Country> objects with their ISO 3166 alpha2 codes as keys (see L<Locale::Object::DB::Schemata> for more details on those) for all countries using this currency in array context, or a reference in scalar context. The objects have their own attribute methods, so you can do things like this for example:
+
+ foreach my $place (@countries)
+ {
+ print $place->name, "\n";
+ }
+
+Which will list you all the countries that use in that currency. See the documentation for L<Locale::Object::Country> for a listing of country attributes. Note that you can chain methods as well.
+
+ foreach my $place (@countries)
+ {
+ print $place->continent->name, "\n";
+ }
+
+=head2 C<official()>
+
+ my $gb = Locale::Object::Country->new( code_alpha2 => 'gb' );
+
+ print $eng->official($gb); # prints 'true'
+
+Give this method a L<Locale::Object::Country> object, and it will return a 'true' or 'false' value for whether the country the object represents has the language represented by your C<Locale::Object::Language> object as an official language. See L<database.pod> for a note about languages in the database.
+
+=head1 OBSOLETE LANGUAGE CODES
+
+ISO 639 is not immune from change, and there are three codes that changed in 1995: Hebrew (C<he>, was C<iw>), Indonesian (C<id>, was C<in>) and Yiddish (C<yi>, formerly C<ji>). Because the database maintains a one-to-one mapping, the old codes aren't included; if you need to support them for some reason (apparently Java versions previous to 1.4 use 'iw', for example), you'll have to alias them yourself. Thanks to Robin Szemeti (RSZEMETI) for bringing this to my attention.
+
+=head1 KNOWN BUGS
+
+The database of language information is not perfect by a long stretch. In particular, numerous comparatively obscure secondary or regional languages that don't have ISO codes, such as in several African countries and India, are missing. (See note in L<database.pod> about data sources.) Please send any corrections to the author.
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+See the credits for L<Locale::Object>.
+
+=head1 LEGAL
+
+Copyright 2003-2007 Earle Martin. All rights reserved.reserved. L<http://purl.org/net/earlemartin/>
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranty is made of any kind, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=cut
+
Added: trunk/Locale-Object/lib/Locale/Object.pm
===================================================================
--- trunk/Locale-Object/lib/Locale/Object.pm (rev 0)
+++ trunk/Locale-Object/lib/Locale/Object.pm 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,579 @@
+package Locale::Object;
+
+use strict;
+use warnings;
+use Carp;
+
+use Locale::Object::Continent;
+use Locale::Object::Country;
+use Locale::Object::Currency;
+use Locale::Object::Language;
+
+our $VERSION = '0.77';
+
+sub new
+{
+ my $class = shift;
+ my %params = @_;
+
+ my $self = bless {}, $class;
+
+ # Initialize the new object or return an existing one.
+ $self->init(%params);
+}
+
+sub init
+{
+ my $self = shift;
+ my %params = @_;
+
+ # Make a hash of valid parameters.
+ my %allowed_params = map { $_ => undef }
+ qw( country_code_alpha2 country_code_alpha3 country_code_numeric
+ currency_code currency_code_numeric currency_name
+ language_code_alpha2 language_code_alpha3 language_name );
+
+ foreach my $parameter (keys %params)
+ {
+ # Go no further if the specified parameter wasn't one.
+ croak "Error: Initialization parameter $parameter unrecognized." unless exists $allowed_params{$parameter};
+
+ $self->$parameter( $params{$parameter} );
+ }
+
+ $self;
+}
+
+# Check 'sanity' of object - that is, whether attributes correspond with each other
+# (no mixing of, say, currency from one country with language from another).
+
+sub sane
+{
+ my $self = shift;
+ my $what = shift;
+
+ # Default attribute is country.
+ $what = 'country' unless $what;
+
+ # Make a hash of allowed attributes.
+ my %attributes = map { $_ => undef } qw( country currency language );
+
+ croak "ERROR: attribute to check sanity against ($what) unrecognized, must be one of 'country', 'currency', 'language'." unless exists $attributes{$what};
+
+ # We want to compare our selected attribute against the remaining attributes,
+ # which will be whatever's left after deleting it from our attributes list.
+ delete $attributes{$what};
+
+ my $sanity_level = 0;
+
+ # Compare each of the other attributes.
+ foreach (keys %attributes)
+ {
+ $sanity_level++ if $self->_compare( from => $_, to => $what ) == 1;
+ }
+
+ # It's only sane if both the other attributes matched.
+ return 1 if $sanity_level == 2;
+
+ 0;
+}
+
+# Compare object attributes against each other.
+# Horrible, horrible code.
+
+sub _compare
+{
+ my $self = shift;
+ my %params = @_;
+
+ my $from = '_' . $params{from};
+ my $to = '_' . $params{to};
+
+ # Pointless but we won't forbid it.
+ return 1 if $params{from} eq $params{to};
+
+ # An empty attribute is a sane attribute.
+ return 1 unless $self->{$from};
+
+ if ($params{to} eq 'country')
+ {
+ foreach my $place ($self->{$from}->countries)
+ {
+ # If any of the countries we're checking match the code
+ # of $self->{_country}, it's sane.
+ return 1 if $place->code_alpha2 eq $self->{_country}->code_alpha2;
+ }
+ }
+
+ elsif ($params{to} eq 'language')
+ {
+ if ($params{from} eq 'country')
+ {
+ foreach ($self->{_country}->languages)
+ {
+ # If $self->{_language} is one of those, it's sane.
+ return 1 if $_->code_alpha2 eq $self->{_language}->code_alpha2;
+ }
+ }
+
+ elsif ($params{from} eq 'currency')
+ {
+ my %languages;
+
+ # Check the alpha2 codes of all the languages used
+ # in all the countries that use that currency.
+ foreach ($self->{_currency}->countries)
+ {
+ foreach ($_->languages)
+ {
+ # If $self->{_language}'s alpha2 code is one of those, it's sane.
+ return 1 if $_->code_alpha2 eq $self->{_language}->code_alpha2;
+ }
+ }
+ }
+ }
+
+ elsif ($params{to} eq 'currency')
+ {
+ if ($params{from} eq 'country')
+ {
+ foreach ($self->{_currency}->countries)
+ {
+ # If any of the countries we're checking match the code
+ # of $self->{_country}, it's sane.
+ return 1 if $_->code_alpha2 eq $self->{_country}->code_alpha2;
+ }
+ }
+
+ elsif ($params{from} eq 'language')
+ {
+ # Check the codes of all the currencies used
+ # in all the countries that use that language.
+ foreach ($self->{_language}->countries)
+ {
+ foreach ($_->currency)
+ {
+ # If $self->{_currency}'s code is one of those, it's sane.
+ return 1 if $_->code eq $self->{_currency}->code;
+ }
+ }
+ }
+ }
+
+ 0;
+}
+
+# Make all the attributes kinsmen.
+
+sub make_sane
+{
+ my $self = shift;
+ my %params = @_;
+
+ my $what = $params{attribute};
+ my $populate = $params{populate} || 0;
+
+ # Make a hash of allowed attributes.
+ my %attributes = map { $_ => undef } qw( country currency language );
+
+ # Default attribute is country.
+ $what = 'country' unless $what;
+
+ croak qq{ERROR: attribute to make sane with ("$what") unrecognized; must be one of "country", "currency", "language".} unless exists $attributes{$what};
+
+ # Internal attributes start with underscores.
+ my $internal_attribute = '_' . $what;
+
+ croak "ERROR: can not make sane against $what, none has been set." unless $self->{$internal_attribute};
+
+ delete $attributes{$what};
+
+ if ($what eq 'country')
+ {
+ # Set the currency attribute with the currency used by the country attribute.
+ $self->currency_code($self->{_country}->currency->code) if $self->{_currency} or $populate == 1;
+
+ # Find the first language belonging to the country attribute that's
+ # listed as official, and set it as the language attribute.
+ if ($self->{_language} or $populate == 1)
+ {
+ $self->language_code_alpha2(
+ @{$self->{_country}->languages_official}[0]->code_alpha2
+ );
+ }
+ }
+ elsif ($what eq 'language')
+ {
+ my $country;
+
+ # If the country attribute exists, check if it uses the language. If so, pick it.
+ if ($self->{_country})
+ {
+ foreach ($self->{_language}->countries)
+ {
+ $country = $_ if $self->{_country}->code_alpha2 eq $_->code_alpha2;
+ }
+ }
+
+ unless (defined $country)
+ {
+ # If no country attribute exists, pick the first country that uses
+ # the language officially.
+ foreach ($self->{_language}->countries)
+ {
+ if ($self->{_language}->official($_) eq 'true')
+ {
+ $country = $_;
+ last;
+ }
+ }
+ }
+
+ $self->country_code_alpha2($country->code_alpha2) if $self->{_country} or $populate == 1;
+ $self->currency_code($country->currency->code) if $self->{_currency} or $populate == 1;
+ }
+ elsif ($what eq 'currency')
+ {
+ my ($country, $language);
+
+ # Try and cross-reference against language.
+ if ($self->{_language})
+ {
+ foreach ($self->{_language}->countries)
+ {
+ # If the currency of a country using our language
+ # matches our currency attribute, pick that country.
+ $country = $_ if ($_->currency->code eq $self->{_currency}->code)
+ }
+ }
+
+ # If the preceding didn't find a country, get the first one to use the currency.
+ $country = @{$self->{_currency}->countries}[0] unless defined $country;
+
+ # Get the first official language of that country.
+ $language = @{$country->languages_official}[0];
+
+ $self->country_code_alpha2($country->code_alpha2) if $self->{_country} or $populate == 1;
+ $self->language_code_alpha2($language->code_alpha2) if $self->{_language} or $populate == 1;
+ }
+
+ $self;
+}
+
+# Remove attributes.
+sub empty
+{
+ my $self = shift;
+ my $attribute = shift;
+
+ $attribute = '_' . $attribute;
+
+ # Make a hash of allowed attributes.
+ my %valid = map { $_ => undef } qw( _country _currency _language );
+
+ croak "ERROR: No attribute specified to empty." unless $attribute;
+ croak qq{ERROR: Invalid attribute ("$attribute") specified to be emptied.} unless exists $valid{$attribute};
+
+ delete $self->{$attribute};
+
+ $self;
+}
+
+# Small methods that set or get object attributes.
+# Could do with being refactored into an AUTOLOAD.
+
+sub country_code_alpha2
+{
+ my $self = shift;
+
+ croak "No value given for country_code_alpha2" unless @_;
+
+ $self->{_country} = Locale::Object::Country->new( code_alpha2 => shift );
+}
+
+sub country_code_alpha3
+{
+ my $self = shift;
+
+ croak "No value given for country_code_alpha3" unless @_;
+
+ $self->{_country} = Locale::Object::Country->new( code_alpha3 => shift );
+}
+
+sub country_code_numeric
+{
+ my $self = shift;
+
+ croak "No value given for country_code_numeric" unless @_;
+
+ $self->{_country} = Locale::Object::Country->new( code_numeric => shift );
+}
+
+sub country_name
+{
+ my $self = shift;
+
+ croak "No value given for country_name" unless @_;
+
+ $self->{_country} = Locale::Object::Country->new( name => shift );
+}
+
+sub currency_code
+{
+ my $self = shift;
+
+ croak 'No value given for currency_code' unless @_;
+
+ $self->{_currency} = Locale::Object::Currency->new( code => shift );
+}
+
+sub currency_code_numeric
+{
+ my $self = shift;
+
+ croak 'No value given for currency_code_numeric' unless @_;
+
+ $self->{_currency} = Locale::Object::Currency->new( code_numeric => shift );
+}
+
+sub language_code_alpha2
+{
+ my $self = shift;
+
+ croak 'No value given for language_code' unless @_;
+
+ $self->{_language} = Locale::Object::Language->new( code_alpha2 => shift );
+}
+
+sub language_code_alpha3
+{
+ my $self = shift;
+
+ croak 'No value given for language_code_alpha3' unless @_;
+
+ $self->{_language} = Locale::Object::Language->new( code_alpha3 => shift );
+}
+
+sub language_name
+{
+ my $self = shift;
+
+ croak 'No value given for language_name' unless @_;
+
+ $self->{_language} = Locale::Object::Language->new( name => shift );
+}
+
+sub language
+{
+ my $self = shift;
+
+ return $self->{_language};
+}
+
+sub country
+{
+ my $self = shift;
+
+ return $self->{_country};
+}
+
+sub currency
+{
+ my $self = shift;
+
+ return $self->{_currency};
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Locale::Object - An object-oriented representation of locale information.
+
+=head1 DESCRIPTION
+
+The C<Locale::Object> group of modules attempts to provide locale-related information in an object-oriented fashion. The information is collated from several sources and provided in an accompanying L<DBD::SQLite> database.
+
+At present, the modules are:
+
+=over 4
+
+=item * L<Locale::Object> - make compound objects containing country, currency and language objects
+
+=item * L<Locale::Object::Country> - objects representing countries
+
+=item * L<Locale::Object::Continent> - objects representing continents
+
+=item * L<Locale::Object::Currency> - objects representing currencies
+
+=item * L<Locale::Object::Currency::Converter> - convert between currencies
+
+=item * L<Locale::Object::DB> - does lookups for the modules in the database
+
+=item * L<Locale::Object::Language> - objects representing languages
+
+=back
+
+For more information, see the documentation for those modules. The database is documented in docs/database.pod. Locale::Object itself can be used to create compound objects containing country, currency and language objects.
+
+=head1 SYNOPSIS
+
+ use Locale::Object;
+
+ my $obj = Locale::Object->new(
+ country_code_alpha2 => 'gb',
+ currency_code => 'GBP',
+ language_code_alpha2 => 'en'
+ );
+
+ $obj->country_code_alpha2('af');
+ $obj->country_code_alpha3('afg');
+
+ $obj->currency_code('AFA');
+ $obj->currency_code_numeric('004');
+
+ $obj->language_code_alpha2('ps');
+ $obj->language_code_alpha3('pus');
+ $obj->language_name('Pushto');
+
+ my $country = $obj->country;
+ my $currency = $obj->currency;
+ my $language = $obj->language;
+
+ $obj->empty('language');
+
+ print $obj->sane('country');
+
+ $obj->make_sane(
+ attribute => 'country'
+ populate => 1
+ );
+
+=head1 METHODS
+
+=head2 C<new()>
+
+ my $obj = Locale::Object->new(
+ country_code_alpha2 => 'gb',
+ currency_code => 'GBP',
+ language_code_alpha2 => 'en'
+ );
+
+Creates a new object. With no parameters, the object will be blank. Valid parameters match the method names that follow.
+
+=head2 C<country_code_alpha2(), country_code_alpha3()>
+
+ $obj->country_code_alpha2('af');
+ $obj->country_code_alpha3('afg');
+
+Sets the country attribute in the object by alpha2 and alpha3 codes. Will create a new L<Locale::Object::Country> object and set that as the attribute. Because Locale::Object::Country objects all have single instances, if one has already been created by that code, it will be reused when you do this.
+
+=head2 C<country_code(), currency_code_numeric()>
+
+ $obj->currency_code('AFA');
+ $obj->currency_code_numeric('004');
+
+Serves the same purpose as the previous methods, only for the currency attribute, a L<Locale::Object::Currency> object.
+
+=head2 C<language_code_alpha2(), language_code_alpha3(), language_name()>
+
+ $obj->language_code_alpha2('ps');
+ $obj->language_code_alpha3('pus');
+ $obj->language_name('Pushto');
+
+Serves the same purpose as the previous methods, only for the language attribute, a L<Locale::Object::Language> object.
+
+=head1 Retrieving and Removing Attributes
+
+=head2 C<country(), language(), currency()>
+
+While the foregoing methods can be used to set attribute objects, to retrieve those objects' own attributes you will have to use their own methods. The C<country()>, C<language()> and C<currency()> methods return the objects stored as those attributes, if they exist.
+
+ my $country_tzone = $country->timezone->name;
+ my $language_name = $obj->language->name;
+ my $currency_code = $obj->currency->code;
+
+See L<Locale::Object::Country>, L<Locale::Object::Language> and L<Locale::Object::Currency> for more details on the subordinate methods.
+
+=head2 C<empty()>
+
+ $obj->empty('language');
+
+Remove an attribute from the object. Can be one of C<country>, C<currency>, C<language>.
+
+=head1 Object Sanity
+
+=head2 C<sane()>
+
+There will be occasions you want to know whether all the attributes in your object make sense with each other - questions such as "is the currency of the object used in the country?" or "Do they speak the language of the object in that country?" For that, use C<sane()>.
+
+ print $obj->sane('country');
+
+Returns 1 if the two remaining attributes in the object make sense compared against the attribute name you specify (if not specified, country is the default); otherwise, 0. The following table explains what's needed for a result of 1. Note: if an attribute doesn't exist, it's not *not* sane, so checking sanity against an attribute in an object with no other attributes will give a result of 1.
+
+ If sane against | country must | language must | currency must
+ -----------------------------------------------------------------------------------------
+ country | n/a | be used in the country | be used in the country
+ -----------------------------------------------------------------------------------------
+ language | be using the language | n/a | be used in a country
+ | | | speaking the language
+ -----------------------------------------------------------------------------------------
+ currency | use the currency | be spoken in a country | n/a
+ | | using the currency |
+
+=head2 C<make_sane()>
+
+ $obj->make_sane(
+ attribute => 'country'
+ populate => 1
+ );
+
+This method will do its best to make the attributes of the object correspond with each other. The attribute you specify as a parameter will be taken to align against (default is country if none specified). If you specify C<populate> as 1, any empty attributes in the object will be filled. Provisos:
+
+=over 4
+
+=item 1) Languages can be used in multiple countries. If you C<make_sane> against language, to pick a country the module will choose the first country it finds that uses the language officially.
+
+=item 2) A similar situation exists for currencies. If a language attribute already exists, the module will pick the first country it finds that speaks the language and uses the currency. Otherwise, it will select the first country in its list of countries using the currency.
+
+=back
+
+=head1 AUTHOR
+
+Earle Martin <hex at cpan.org>
+
+=over 4
+
+=item L<http://downlode.org/Code/Perl/>
+
+=back
+
+=head1 CREDITS
+
+=over 4
+
+=item * Original concept: Pierre Denis (PDENIS)
+
+=item * Assistance: Tom Insam (TOMI), James Duncan (JDUNCAN)
+
+=item * Teaching: Damian Conway (DCONWAY)'s excellent book "Object Oriented Perl" (ISBN 1884777791)
+
+=item * Bugfixes, patches: Ask Bjoern Hansen (ABH), Tom Insam again
+
+=item * Tips, testing: Jost Krieger, Barbie (BARBIE), Nathan McFarland (NMCFARL)
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2003-2007 Earle Martin. All rights reserved.
+
+This module is released under the same license as Perl itself, and is provided on an "as is" basis. No warranties of any kind are made, either expressed or implied, as to the accuracy and/or utility of any results obtained from its use. However, if you do find something wrong with the results, please let the author know. Thanks.
+
+=head1 SEE ALSO
+
+L<Locale::Codes>, for simple conversions between names and ISO codes.
+
+=cut
Added: trunk/Locale-Object/lib/copy-for-test.PL
===================================================================
--- trunk/Locale-Object/lib/copy-for-test.PL (rev 0)
+++ trunk/Locale-Object/lib/copy-for-test.PL 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use File::Copy;
+
+my @dirs = ('blib/', 'lib/', 'Locale/', 'Object');
+
+my $where = '';
+
+foreach my $dir (@dirs)
+{
+ $where = $where . $dir;
+
+ mkdir $where;
+ die "Couldn't make $where directory: $!" unless $! =~ /File exists/;
+}
+
+copy('lib/Locale/Object/locale.db', 'blib/lib/Locale/Object/locale.db')
+ or die "Couldn't copy locale database: $!";
+
+=head1 NAME
+
+copy-for-test.PL - ensure ./Build test works
+
+=head1 DESCRIPTION
+
+The L<Locale::Object> modules use a L<DBD::SQLite> database of information
+that they consult, which is created at build time. That file needs to be in the
+same directory as L<Locale::Object::DB>.
+
+Because L<Module::Build> won't copy non-Perl files into the C<blib> directory
+when you run the tests, this script copies the DB into
+C<blib/lib/Locale/Object/> (creating those directories, if need be) when you do
+C<./Build>. That way, L<Locale::Object::DB> will be able to find it when you do
+a C<./Build test>.
+
+There should be no need to run this script yourself.
+
+=cut
Property changes on: trunk/Locale-Object/lib/copy-for-test.PL
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/Locale-Object/locale.sql
===================================================================
--- trunk/Locale-Object/locale.sql (rev 0)
+++ trunk/Locale-Object/locale.sql 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,1963 @@
+BEGIN TRANSACTION;
+CREATE TABLE continent (
+ country_code char(2),
+ name char(13),
+ PRIMARY KEY (country_code)
+);
+INSERT INTO continent VALUES('ad','Europe');
+INSERT INTO continent VALUES('ae','Asia');
+INSERT INTO continent VALUES('af','Asia');
+INSERT INTO continent VALUES('ag','North America');
+INSERT INTO continent VALUES('ai','North America');
+INSERT INTO continent VALUES('al','Europe');
+INSERT INTO continent VALUES('am','Europe');
+INSERT INTO continent VALUES('ao','Africa');
+INSERT INTO continent VALUES('ar','South America');
+INSERT INTO continent VALUES('as','North America');
+INSERT INTO continent VALUES('at','Europe');
+INSERT INTO continent VALUES('au','Oceania');
+INSERT INTO continent VALUES('aw','North America');
+INSERT INTO continent VALUES('az','Europe');
+INSERT INTO continent VALUES('ba','Europe');
+INSERT INTO continent VALUES('bb','North America');
+INSERT INTO continent VALUES('bd','Asia');
+INSERT INTO continent VALUES('be','Europe');
+INSERT INTO continent VALUES('bg','Europe');
+INSERT INTO continent VALUES('bh','Asia');
+INSERT INTO continent VALUES('bi','Africa');
+INSERT INTO continent VALUES('bj','Africa');
+INSERT INTO continent VALUES('bm','North America');
+INSERT INTO continent VALUES('bo','South America');
+INSERT INTO continent VALUES('br','South America');
+INSERT INTO continent VALUES('bs','North America');
+INSERT INTO continent VALUES('bt','Asia');
+INSERT INTO continent VALUES('bw','Africa');
+INSERT INTO continent VALUES('by','Europe');
+INSERT INTO continent VALUES('bz','North America');
+INSERT INTO continent VALUES('ca','North America');
+INSERT INTO continent VALUES('cf','Africa');
+INSERT INTO continent VALUES('cg','Africa');
+INSERT INTO continent VALUES('ch','Europe');
+INSERT INTO continent VALUES('ci','Africa');
+INSERT INTO continent VALUES('cl','South America');
+INSERT INTO continent VALUES('cm','Africa');
+INSERT INTO continent VALUES('cn','Asia');
+INSERT INTO continent VALUES('co','South America');
+INSERT INTO continent VALUES('cr','North America');
+INSERT INTO continent VALUES('cu','North America');
+INSERT INTO continent VALUES('cv','Africa');
+INSERT INTO continent VALUES('cy','Europe');
+INSERT INTO continent VALUES('cz','Europe');
+INSERT INTO continent VALUES('de','Europe');
+INSERT INTO continent VALUES('dj','Africa');
+INSERT INTO continent VALUES('dk','Europe');
+INSERT INTO continent VALUES('dm','North America');
+INSERT INTO continent VALUES('do','North America');
+INSERT INTO continent VALUES('dz','Africa');
+INSERT INTO continent VALUES('ec','South America');
+INSERT INTO continent VALUES('ee','Europe');
+INSERT INTO continent VALUES('eg','Africa');
+INSERT INTO continent VALUES('eh','Africa');
+INSERT INTO continent VALUES('er','Africa');
+INSERT INTO continent VALUES('es','Europe');
+INSERT INTO continent VALUES('et','Africa');
+INSERT INTO continent VALUES('fi','Europe');
+INSERT INTO continent VALUES('fj','Oceania');
+INSERT INTO continent VALUES('fk','South America');
+INSERT INTO continent VALUES('fr','Europe');
+INSERT INTO continent VALUES('fx','Europe');
+INSERT INTO continent VALUES('ga','Africa');
+INSERT INTO continent VALUES('gb','Europe');
+INSERT INTO continent VALUES('gd','North America');
+INSERT INTO continent VALUES('ge','Europe');
+INSERT INTO continent VALUES('gf','South America');
+INSERT INTO continent VALUES('gh','Africa');
+INSERT INTO continent VALUES('gi','Europe');
+INSERT INTO continent VALUES('gl','Europe');
+INSERT INTO continent VALUES('gm','Africa');
+INSERT INTO continent VALUES('gn','Africa');
+INSERT INTO continent VALUES('gp','South America');
+INSERT INTO continent VALUES('gq','Africa');
+INSERT INTO continent VALUES('gr','Europe');
+INSERT INTO continent VALUES('gt','North America');
+INSERT INTO continent VALUES('gw','Africa');
+INSERT INTO continent VALUES('gy','South America');
+INSERT INTO continent VALUES('hk','Asia');
+INSERT INTO continent VALUES('hn','North America');
+INSERT INTO continent VALUES('hr','Europe');
+INSERT INTO continent VALUES('ht','North America');
+INSERT INTO continent VALUES('hu','Europe');
+INSERT INTO continent VALUES('id','Asia');
+INSERT INTO continent VALUES('ie','Europe');
+INSERT INTO continent VALUES('il','Asia');
+INSERT INTO continent VALUES('in','Asia');
+INSERT INTO continent VALUES('iq','Asia');
+INSERT INTO continent VALUES('ir','Asia');
+INSERT INTO continent VALUES('is','Europe');
+INSERT INTO continent VALUES('it','Europe');
+INSERT INTO continent VALUES('jm','North America');
+INSERT INTO continent VALUES('jo','Asia');
+INSERT INTO continent VALUES('jp','Asia');
+INSERT INTO continent VALUES('ke','Africa');
+INSERT INTO continent VALUES('kg','Asia');
+INSERT INTO continent VALUES('kh','Asia');
+INSERT INTO continent VALUES('ki','Oceania');
+INSERT INTO continent VALUES('km','Africa');
+INSERT INTO continent VALUES('kn','North America');
+INSERT INTO continent VALUES('kp','Asia');
+INSERT INTO continent VALUES('kr','Asia');
+INSERT INTO continent VALUES('kw','Asia');
+INSERT INTO continent VALUES('kz','Asia');
+INSERT INTO continent VALUES('la','Asia');
+INSERT INTO continent VALUES('lb','Asia');
+INSERT INTO continent VALUES('lc','North America');
+INSERT INTO continent VALUES('li','Europe');
+INSERT INTO continent VALUES('lk','Asia');
+INSERT INTO continent VALUES('lr','Africa');
+INSERT INTO continent VALUES('ls','Africa');
+INSERT INTO continent VALUES('lt','Europe');
+INSERT INTO continent VALUES('lu','Europe');
+INSERT INTO continent VALUES('lv','Europe');
+INSERT INTO continent VALUES('ly','Africa');
+INSERT INTO continent VALUES('ma','Africa');
+INSERT INTO continent VALUES('mc','Europe');
+INSERT INTO continent VALUES('md','Europe');
+INSERT INTO continent VALUES('mg','Africa');
+INSERT INTO continent VALUES('mh','Oceania');
+INSERT INTO continent VALUES('mk','Europe');
+INSERT INTO continent VALUES('ml','Africa');
+INSERT INTO continent VALUES('mm','Asia');
+INSERT INTO continent VALUES('mn','Asia');
+INSERT INTO continent VALUES('mo','Asia');
+INSERT INTO continent VALUES('mq','North America');
+INSERT INTO continent VALUES('mr','Africa');
+INSERT INTO continent VALUES('ms','North America');
+INSERT INTO continent VALUES('mt','Europe');
+INSERT INTO continent VALUES('mu','Africa');
+INSERT INTO continent VALUES('mv','Asia');
+INSERT INTO continent VALUES('mw','Africa');
+INSERT INTO continent VALUES('mx','North America');
+INSERT INTO continent VALUES('my','Asia');
+INSERT INTO continent VALUES('mz','Africa');
+INSERT INTO continent VALUES('na','Africa');
+INSERT INTO continent VALUES('ne','Africa');
+INSERT INTO continent VALUES('ng','Africa');
+INSERT INTO continent VALUES('ni','North America');
+INSERT INTO continent VALUES('nl','Europe');
+INSERT INTO continent VALUES('no','Europe');
+INSERT INTO continent VALUES('np','Asia');
+INSERT INTO continent VALUES('nr','Oceania');
+INSERT INTO continent VALUES('nz','Oceania');
+INSERT INTO continent VALUES('om','Asia');
+INSERT INTO continent VALUES('pa','North America');
+INSERT INTO continent VALUES('pe','South America');
+INSERT INTO continent VALUES('pg','Oceania');
+INSERT INTO continent VALUES('ph','Asia');
+INSERT INTO continent VALUES('pk','Asia');
+INSERT INTO continent VALUES('pl','Europe');
+INSERT INTO continent VALUES('pr','North America');
+INSERT INTO continent VALUES('ps','Asia');
+INSERT INTO continent VALUES('pt','Europe');
+INSERT INTO continent VALUES('pw','Oceania');
+INSERT INTO continent VALUES('py','South America');
+INSERT INTO continent VALUES('qa','Asia');
+INSERT INTO continent VALUES('ro','Europe');
+INSERT INTO continent VALUES('ru','Europe');
+INSERT INTO continent VALUES('rw','Africa');
+INSERT INTO continent VALUES('sa','Asia');
+INSERT INTO continent VALUES('sb','Oceania');
+INSERT INTO continent VALUES('sc','Africa');
+INSERT INTO continent VALUES('sd','Africa');
+INSERT INTO continent VALUES('se','Europe');
+INSERT INTO continent VALUES('sg','Asia');
+INSERT INTO continent VALUES('si','Europe');
+INSERT INTO continent VALUES('sk','Europe');
+INSERT INTO continent VALUES('sl','Africa');
+INSERT INTO continent VALUES('sm','Europe');
+INSERT INTO continent VALUES('sn','Africa');
+INSERT INTO continent VALUES('so','Africa');
+INSERT INTO continent VALUES('sr','South America');
+INSERT INTO continent VALUES('st','Africa');
+INSERT INTO continent VALUES('sv','North America');
+INSERT INTO continent VALUES('sy','Asia');
+INSERT INTO continent VALUES('sz','Africa');
+INSERT INTO continent VALUES('td','Africa');
+INSERT INTO continent VALUES('tg','Africa');
+INSERT INTO continent VALUES('th','Asia');
+INSERT INTO continent VALUES('tj','Asia');
+INSERT INTO continent VALUES('tm','Asia');
+INSERT INTO continent VALUES('tn','Africa');
+INSERT INTO continent VALUES('to','Oceania');
+INSERT INTO continent VALUES('tl','Asia');
+INSERT INTO continent VALUES('tr','Asia');
+INSERT INTO continent VALUES('tt','North America');
+INSERT INTO continent VALUES('tv','Oceania');
+INSERT INTO continent VALUES('tw','Asia');
+INSERT INTO continent VALUES('tz','Africa');
+INSERT INTO continent VALUES('ua','Europe');
+INSERT INTO continent VALUES('ug','Africa');
+INSERT INTO continent VALUES('um','North America');
+INSERT INTO continent VALUES('us','North America');
+INSERT INTO continent VALUES('uy','South America');
+INSERT INTO continent VALUES('uz','Asia');
+INSERT INTO continent VALUES('va','Europe');
+INSERT INTO continent VALUES('vc','North America');
+INSERT INTO continent VALUES('ve','South America');
+INSERT INTO continent VALUES('vn','Asia');
+INSERT INTO continent VALUES('ws','Oceania');
+INSERT INTO continent VALUES('ye','Asia');
+INSERT INTO continent VALUES('yu','Europe');
+INSERT INTO continent VALUES('za','Africa');
+INSERT INTO continent VALUES('zm','Africa');
+INSERT INTO continent VALUES('zr','Africa');
+INSERT INTO continent VALUES('zw','Africa');
+INSERT INTO continent VALUES('vg','North America');
+INSERT INTO continent VALUES('tc','North America');
+INSERT INTO continent VALUES('vi','North America');
+INSERT INTO continent VALUES('gu','North America');
+INSERT INTO continent VALUES('vu','Oceania');
+INSERT INTO continent VALUES('bn','Asia');
+INSERT INTO continent VALUES('an','Oceania');
+INSERT INTO continent VALUES('bf','Oceania');
+INSERT INTO continent VALUES('bv','Oceania');
+INSERT INTO continent VALUES('cc','Oceania');
+INSERT INTO continent VALUES('ck','Oceania');
+INSERT INTO continent VALUES('cx','Oceania');
+INSERT INTO continent VALUES('fm','Oceania');
+INSERT INTO continent VALUES('fo','Oceania');
+INSERT INTO continent VALUES('gs','Oceania');
+INSERT INTO continent VALUES('hm','Oceania');
+INSERT INTO continent VALUES('io','Oceania');
+INSERT INTO continent VALUES('ky','Oceania');
+INSERT INTO continent VALUES('mp','Oceania');
+INSERT INTO continent VALUES('nc','Oceania');
+INSERT INTO continent VALUES('nf','Oceania');
+INSERT INTO continent VALUES('nu','Oceania');
+INSERT INTO continent VALUES('pf','Oceania');
+INSERT INTO continent VALUES('pm','Oceania');
+INSERT INTO continent VALUES('pn','Oceania');
+INSERT INTO continent VALUES('re','Oceania');
+INSERT INTO continent VALUES('sh','Oceania');
+INSERT INTO continent VALUES('sj','Oceania');
+INSERT INTO continent VALUES('tf','Oceania');
+INSERT INTO continent VALUES('tk','Oceania');
+INSERT INTO continent VALUES('wf','Oceania');
+INSERT INTO continent VALUES('yt','Oceania');
+INSERT INTO continent VALUES('aq','Antarctica');
+INSERT INTO continent VALUES('cd','Africa');
+CREATE TABLE country (
+ code_alpha2 char(2),
+ code_alpha3 char(3),
+ code_numeric char(5),
+ name char(100),
+ dialing_code smallint,
+ PRIMARY KEY (code_alpha2)
+);
+INSERT INTO country VALUES('ad','and','020','Andorra',376);
+INSERT INTO country VALUES('ae','are','784','United Arab Emirates',971);
+INSERT INTO country VALUES('af','afg','004','Afghanistan',93);
+INSERT INTO country VALUES('ag','atg','028','Antigua and Barbuda',1268);
+INSERT INTO country VALUES('ai','aia','660','Anguilla',1264);
+INSERT INTO country VALUES('al','alb','008','Albania',355);
+INSERT INTO country VALUES('am','arm','051','Armenia',374);
+INSERT INTO country VALUES('an','ant','530','Netherlands Antilles',599);
+INSERT INTO country VALUES('ao','ago','024','Angola',244);
+INSERT INTO country VALUES('aq','ata','010','Antarctica',672);
+INSERT INTO country VALUES('ar','arg','032','Argentina',54);
+INSERT INTO country VALUES('as','asm','016','American Samoa',684);
+INSERT INTO country VALUES('at','aut','040','Austria',43);
+INSERT INTO country VALUES('au','aus','036','Australia',61);
+INSERT INTO country VALUES('aw','abw','533','Aruba',297);
+INSERT INTO country VALUES('az','aze','031','Azerbaijan',994);
+INSERT INTO country VALUES('ba','bih','070','Bosnia and Herzegovina',387);
+INSERT INTO country VALUES('bb','brb','052','Barbados',1246);
+INSERT INTO country VALUES('bd','bgd','050','Bangladesh',880);
+INSERT INTO country VALUES('be','bel','056','Belgium',32);
+INSERT INTO country VALUES('bf','bfa','854','Burkina Faso',226);
+INSERT INTO country VALUES('bg','bgr','100','Bulgaria',359);
+INSERT INTO country VALUES('bh','bhr','048','Bahrain',973);
+INSERT INTO country VALUES('bi','bdi','108','Burundi',257);
+INSERT INTO country VALUES('bj','ben','204','Benin',229);
+INSERT INTO country VALUES('bm','bmu','060','Bermuda',1441);
+INSERT INTO country VALUES('bn','brn','096','Brunei Darussalam',673);
+INSERT INTO country VALUES('bo','bol','068','Bolivia',591);
+INSERT INTO country VALUES('br','bra','076','Brazil',55);
+INSERT INTO country VALUES('bs','bhs','044','Bahamas',1242);
+INSERT INTO country VALUES('bt','btn','064','Bhutan',975);
+INSERT INTO country VALUES('bv','bvt','074','Bouvet Island',NULL);
+INSERT INTO country VALUES('bw','bwa','072','Botswana',267);
+INSERT INTO country VALUES('by','blr','112','Belarus',375);
+INSERT INTO country VALUES('bz','blz','084','Belize',501);
+INSERT INTO country VALUES('ca','can','124','Canada',1);
+INSERT INTO country VALUES('cc','cck','166','Cocos (Keeling) Islands',61);
+INSERT INTO country VALUES('cf','caf','140','Central African Republic',236);
+INSERT INTO country VALUES('cg','cog','178','Congo',242);
+INSERT INTO country VALUES('ch','che','756','Switzerland',41);
+INSERT INTO country VALUES('ci','civ','384','Cote D''Ivoire',225);
+INSERT INTO country VALUES('ck','cok','184','Cook Islands',682);
+INSERT INTO country VALUES('cl','chl','152','Chile',56);
+INSERT INTO country VALUES('cm','cmr','120','Cameroon',237);
+INSERT INTO country VALUES('cn','chn','156','China',86);
+INSERT INTO country VALUES('co','col','170','Colombia',57);
+INSERT INTO country VALUES('cr','cri','188','Costa Rica',506);
+INSERT INTO country VALUES('cu','cub','192','Cuba',53);
+INSERT INTO country VALUES('cv','cpv','132','Cape Verde',238);
+INSERT INTO country VALUES('cx','cxr','162','Christmas Island',618);
+INSERT INTO country VALUES('cy','cyp','196','Cyprus',357);
+INSERT INTO country VALUES('cz','cze','203','Czech Republic',420);
+INSERT INTO country VALUES('de','deu','276','Germany',49);
+INSERT INTO country VALUES('dj','dji','262','Djibouti',253);
+INSERT INTO country VALUES('dk','dnk','208','Denmark',45);
+INSERT INTO country VALUES('dm','dma','212','Dominica',1767);
+INSERT INTO country VALUES('do','dom','214','Dominican Republic',1809);
+INSERT INTO country VALUES('dz','dza','012','Algeria',213);
+INSERT INTO country VALUES('ec','ecu','218','Ecuador',593);
+INSERT INTO country VALUES('ee','est','233','Estonia',372);
+INSERT INTO country VALUES('eg','egy','818','Egypt',20);
+INSERT INTO country VALUES('eh','esh','732','Western Sahara',NULL);
+INSERT INTO country VALUES('er','eri','232','Eritrea',291);
+INSERT INTO country VALUES('es','esp','724','Spain',34);
+INSERT INTO country VALUES('et','eth','231','Ethiopia',251);
+INSERT INTO country VALUES('fi','fin','246','Finland',358);
+INSERT INTO country VALUES('fj','fji','242','Fiji',679);
+INSERT INTO country VALUES('fk','flk','238','Falkland Islands (Malvinas)',500);
+INSERT INTO country VALUES('fm','fsm','583','Micronesia, Federated States of',691);
+INSERT INTO country VALUES('fo','fro','234','Faroe Islands',298);
+INSERT INTO country VALUES('fr','fra','250','France',33);
+INSERT INTO country VALUES('fx','fxx','249','France, Metropolitan',NULL);
+INSERT INTO country VALUES('ga','gab','266','Gabon',241);
+INSERT INTO country VALUES('gb','gbr','826','United Kingdom',44);
+INSERT INTO country VALUES('gd','grd','308','Grenada',1473);
+INSERT INTO country VALUES('ge','geo','268','Georgia',995);
+INSERT INTO country VALUES('gf','guf','254','French Guiana',594);
+INSERT INTO country VALUES('gh','gha','288','Ghana',233);
+INSERT INTO country VALUES('gi','gib','292','Gibraltar',350);
+INSERT INTO country VALUES('gl','grl','304','Greenland',299);
+INSERT INTO country VALUES('gm','gmb','270','Gambia',220);
+INSERT INTO country VALUES('gn','gin','324','Guinea',224);
+INSERT INTO country VALUES('gp','glp','312','Guadeloupe',590);
+INSERT INTO country VALUES('gq','gnq','226','Equatorial Guinea',240);
+INSERT INTO country VALUES('gr','grc','300','Greece',30);
+INSERT INTO country VALUES('gs','sgs','239','South Georgia and the South Sandwich Islands',NULL);
+INSERT INTO country VALUES('gt','gtm','320','Guatemala',502);
+INSERT INTO country VALUES('gu','gum','316','Guam',1671);
+INSERT INTO country VALUES('gw','gnb','624','Guinea-Bissau',245);
+INSERT INTO country VALUES('gy','guy','328','Guyana',592);
+INSERT INTO country VALUES('hk','hkg','344','Hong Kong',852);
+INSERT INTO country VALUES('hm','hmd','334','Heard Island and McDonald Islands',NULL);
+INSERT INTO country VALUES('hn','hnd','340','Honduras',504);
+INSERT INTO country VALUES('hr','hrv','191','Croatia',385);
+INSERT INTO country VALUES('ht','hti','332','Haiti',509);
+INSERT INTO country VALUES('hu','hun','348','Hungary',36);
+INSERT INTO country VALUES('id','idn','360','Indonesia',62);
+INSERT INTO country VALUES('ie','irl','372','Ireland',353);
+INSERT INTO country VALUES('il','isr','376','Israel',972);
+INSERT INTO country VALUES('in','ind','356','India',91);
+INSERT INTO country VALUES('io','iot','086','British Indian Ocean Territory',NULL);
+INSERT INTO country VALUES('iq','irq','368','Iraq',964);
+INSERT INTO country VALUES('ir','irn','364','Iran, Islamic Republic of',98);
+INSERT INTO country VALUES('is','isl','352','Iceland',354);
+INSERT INTO country VALUES('it','ita','380','Italy',39);
+INSERT INTO country VALUES('jm','jam','388','Jamaica',1876);
+INSERT INTO country VALUES('jo','jor','400','Jordan',962);
+INSERT INTO country VALUES('jp','jpn','392','Japan',81);
+INSERT INTO country VALUES('ke','ken','404','Kenya',254);
+INSERT INTO country VALUES('kg','kgz','417','Kyrgyzstan',996);
+INSERT INTO country VALUES('kh','khm','116','Cambodia',855);
+INSERT INTO country VALUES('ki','kir','296','Kiribati',686);
+INSERT INTO country VALUES('km','com','174','Comoros',269);
+INSERT INTO country VALUES('kn','kna','659','Saint Kitts and Nevis',1869);
+INSERT INTO country VALUES('kp','prk','408','Korea, Democratic People''s Republic of',850);
+INSERT INTO country VALUES('kr','kor','410','Korea, Republic of',850);
+INSERT INTO country VALUES('kw','kwt','414','Kuwait',965);
+INSERT INTO country VALUES('ky','cym','136','Cayman Islands',1345);
+INSERT INTO country VALUES('kz','kaz','398','Kazakhstan',7);
+INSERT INTO country VALUES('la','lao','418','Lao People''s Democratic Republic',856);
+INSERT INTO country VALUES('lb','lbn','422','Lebanon',961);
+INSERT INTO country VALUES('lc','lca','662','Saint Lucia',1758);
+INSERT INTO country VALUES('li','lie','438','Liechtenstein',423);
+INSERT INTO country VALUES('lk','lka','144','Sri Lanka',94);
+INSERT INTO country VALUES('lr','lbr','430','Liberia',231);
+INSERT INTO country VALUES('ls','lso','426','Lesotho',266);
+INSERT INTO country VALUES('lt','ltu','440','Lithuania',370);
+INSERT INTO country VALUES('lu','lux','442','Luxembourg',352);
+INSERT INTO country VALUES('lv','lva','428','Latvia',371);
+INSERT INTO country VALUES('ly','lby','434','Libyan Arab Jamahiriya',218);
+INSERT INTO country VALUES('ma','mar','504','Morocco',212);
+INSERT INTO country VALUES('mc','mco','492','Monaco',377);
+INSERT INTO country VALUES('md','mda','498','Moldova, Republic of',373);
+INSERT INTO country VALUES('mg','mdg','450','Madagascar',261);
+INSERT INTO country VALUES('mh','mhl','584','Marshall Islands',692);
+INSERT INTO country VALUES('mk','mkd','807','Macedonia, the Former Yugoslav Republic of',389);
+INSERT INTO country VALUES('ml','mli','466','Mali',223);
+INSERT INTO country VALUES('mm','mmr','104','Myanmar',95);
+INSERT INTO country VALUES('mn','mng','496','Mongolia',976);
+INSERT INTO country VALUES('mo','mac','446','Macao',853);
+INSERT INTO country VALUES('mp','mnp','580','Northern Mariana Islands',1670);
+INSERT INTO country VALUES('mq','mtq','474','Martinique',596);
+INSERT INTO country VALUES('mr','mrt','478','Mauritania',222);
+INSERT INTO country VALUES('ms','msr','500','Montserrat',1664);
+INSERT INTO country VALUES('mt','mlt','470','Malta',356);
+INSERT INTO country VALUES('mu','mus','480','Mauritius',230);
+INSERT INTO country VALUES('mv','mdv','462','Maldives',960);
+INSERT INTO country VALUES('mw','mwi','454','Malawi',265);
+INSERT INTO country VALUES('mx','mex','484','Mexico',52);
+INSERT INTO country VALUES('my','mys','458','Malaysia',60);
+INSERT INTO country VALUES('mz','moz','508','Mozambique',258);
+INSERT INTO country VALUES('na','nam','516','Namibia',264);
+INSERT INTO country VALUES('nc','ncl','540','New Caledonia',687);
+INSERT INTO country VALUES('ne','ner','562','Niger',227);
+INSERT INTO country VALUES('nf','nfk','574','Norfolk Island',672);
+INSERT INTO country VALUES('ng','nga','566','Nigeria',234);
+INSERT INTO country VALUES('ni','nic','558','Nicaragua',505);
+INSERT INTO country VALUES('nl','nld','528','Netherlands',31);
+INSERT INTO country VALUES('no','nor','578','Norway',47);
+INSERT INTO country VALUES('np','npl','524','Nepal',977);
+INSERT INTO country VALUES('nr','nru','520','Nauru',674);
+INSERT INTO country VALUES('nu','niu','570','Niue',683);
+INSERT INTO country VALUES('nz','nzl','554','New Zealand',64);
+INSERT INTO country VALUES('om','omn','512','Oman',968);
+INSERT INTO country VALUES('pa','pan','591','Panama',507);
+INSERT INTO country VALUES('pe','per','604','Peru',51);
+INSERT INTO country VALUES('pf','pyf','258','French Polynesia',689);
+INSERT INTO country VALUES('pg','png','598','Papua New Guinea',675);
+INSERT INTO country VALUES('ph','phl','608','Philippines',63);
+INSERT INTO country VALUES('pk','pak','586','Pakistan',92);
+INSERT INTO country VALUES('pl','pol','616','Poland',48);
+INSERT INTO country VALUES('pm','spm','666','Saint Pierre and Miquelon',508);
+INSERT INTO country VALUES('pn','pcn','612','Pitcairn',NULL);
+INSERT INTO country VALUES('pr','pri','630','Puerto Rico',1939);
+INSERT INTO country VALUES('ps','pse','275','Palestinian Territory, Occupied',NULL);
+INSERT INTO country VALUES('pt','prt','620','Portugal',351);
+INSERT INTO country VALUES('pw','plw','585','Palau',680);
+INSERT INTO country VALUES('py','pry','600','Paraguay',595);
+INSERT INTO country VALUES('qa','qat','634','Qatar',974);
+INSERT INTO country VALUES('re','reu','638','Reunion',262);
+INSERT INTO country VALUES('ro','rom','642','Romania',40);
+INSERT INTO country VALUES('ru','rus','643','Russian Federation',7);
+INSERT INTO country VALUES('rw','rwa','646','Rwanda',250);
+INSERT INTO country VALUES('sa','sau','682','Saudi Arabia',966);
+INSERT INTO country VALUES('sb','slb','090','Solomon Islands',677);
+INSERT INTO country VALUES('sc','syc','690','Seychelles',248);
+INSERT INTO country VALUES('sd','sdn','736','Sudan',249);
+INSERT INTO country VALUES('se','swe','752','Sweden',46);
+INSERT INTO country VALUES('sg','sgp','702','Singapore',65);
+INSERT INTO country VALUES('sh','shn','654','Saint Helena',290);
+INSERT INTO country VALUES('si','svn','705','Slovenia',386);
+INSERT INTO country VALUES('sj','sjm','744','Svalbard and Jan Mayen',NULL);
+INSERT INTO country VALUES('sk','svk','703','Slovakia',421);
+INSERT INTO country VALUES('sl','sle','694','Sierra Leone',232);
+INSERT INTO country VALUES('sm','smr','674','San Marino',378);
+INSERT INTO country VALUES('sn','sen','686','Senegal',221);
+INSERT INTO country VALUES('so','som','706','Somalia',252);
+INSERT INTO country VALUES('sr','sur','740','Suriname',597);
+INSERT INTO country VALUES('st','stp','678','Sao Tome and Principe',239);
+INSERT INTO country VALUES('sv','slv','222','El Salvador',503);
+INSERT INTO country VALUES('sy','syr','760','Syrian Arab Republic',963);
+INSERT INTO country VALUES('sz','swz','748','Swaziland',268);
+INSERT INTO country VALUES('tc','tca','796','Turks and Caicos Islands',1649);
+INSERT INTO country VALUES('td','tcd','148','Chad',235);
+INSERT INTO country VALUES('tf','atf','260','French Southern Territories',NULL);
+INSERT INTO country VALUES('tg','tgo','768','Togo',228);
+INSERT INTO country VALUES('th','tha','764','Thailand',66);
+INSERT INTO country VALUES('tj','tjk','762','Tajikistan',992);
+INSERT INTO country VALUES('tk','tkl','772','Tokelau',690);
+INSERT INTO country VALUES('tm','tkm','795','Turkmenistan',993);
+INSERT INTO country VALUES('tn','tun','788','Tunisia',216);
+INSERT INTO country VALUES('to','ton','776','Tonga',676);
+INSERT INTO country VALUES('tl','tls','626','East Timor',670);
+INSERT INTO country VALUES('tr','tur','792','Turkey',90);
+INSERT INTO country VALUES('tt','tto','780','Trinidad and Tobago',1868);
+INSERT INTO country VALUES('tv','tuv','798','Tuvalu',688);
+INSERT INTO country VALUES('tw','twn','158','Taiwan, Province of China',886);
+INSERT INTO country VALUES('tz','tza','834','Tanzania, United Republic of',255);
+INSERT INTO country VALUES('ua','ukr','804','Ukraine',380);
+INSERT INTO country VALUES('ug','uga','800','Uganda',256);
+INSERT INTO country VALUES('um','umi','581','United States Minor Outlying Islands',NULL);
+INSERT INTO country VALUES('us','usa','840','United States',1);
+INSERT INTO country VALUES('uy','ury','858','Uruguay',598);
+INSERT INTO country VALUES('uz','uzb','860','Uzbekistan',998);
+INSERT INTO country VALUES('va','vat','336','Holy See (Vatican City State)',379);
+INSERT INTO country VALUES('vc','vct','670','Saint Vincent and the Grenadines',1784);
+INSERT INTO country VALUES('ve','ven','862','Venezuela',58);
+INSERT INTO country VALUES('vg','vgb','092','Virgin Islands, British',1284);
+INSERT INTO country VALUES('vi','vir','850','Virgin Islands, U.S.',1340);
+INSERT INTO country VALUES('vn','vnm','704','Vietnam',84);
+INSERT INTO country VALUES('vu','vut','548','Vanuatu',678);
+INSERT INTO country VALUES('wf','wlf','876','Wallis and Futuna',681);
+INSERT INTO country VALUES('ws','wsm','882','Samoa',685);
+INSERT INTO country VALUES('ye','yem','887','Yemen',967);
+INSERT INTO country VALUES('yt','myt','175','Mayotte',269);
+INSERT INTO country VALUES('yu','yug','891','Yugoslavia',381);
+INSERT INTO country VALUES('za','zaf','710','South Africa',27);
+INSERT INTO country VALUES('zm','zmb','894','Zambia',260);
+INSERT INTO country VALUES('zr','zar','180','Zaire',243);
+INSERT INTO country VALUES('zw','zwe','716','Zimbabwe',263);
+INSERT INTO country VALUES('cd','cod','180','Congo, the Democratic Republic of the',243);
+CREATE TABLE currency (
+ country_code char(2),
+ name char(100),
+ code char(3),
+ code_numeric char(5),
+ symbol char(20),
+ subunit char(100),
+ subunit_amount smallint,
+ PRIMARY KEY (country_code)
+);
+INSERT INTO currency VALUES('ad','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('ae','dirham','AED','784','Dh','fils',100);
+INSERT INTO currency VALUES('af','afghani','AFA','004','Af','puls',100);
+INSERT INTO currency VALUES('ag','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('ai','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('al','lek','ALL','008','L','qindarka',100);
+INSERT INTO currency VALUES('am','dram','AMD','051','','luma',100);
+INSERT INTO currency VALUES('an','guilder','ANG','532','NAf','cents',100);
+INSERT INTO currency VALUES('ao','kwanza','AOA','024','Kz','lwei',100);
+INSERT INTO currency VALUES('aq','none','000',000,NULL,NULL,NULL);
+INSERT INTO currency VALUES('ar','peso','ARS','032','$','centavos',100);
+INSERT INTO currency VALUES('as','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('at','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('au','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('aw','guilder','AWG','533','Af.','cents',100);
+INSERT INTO currency VALUES('az','manat','AZM','031','','gopik',100);
+INSERT INTO currency VALUES('ba','convertible mark','BAM','977','KM','fennig',100);
+INSERT INTO currency VALUES('bb','dollar','BBD','052','Bds$','cents',100);
+INSERT INTO currency VALUES('bd','taka','BDT','050','Tk','paisa',100);
+INSERT INTO currency VALUES('be','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('bf','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('bg','leva','BGL','100','Lv','stotinki',100);
+INSERT INTO currency VALUES('bh','dinar','BHD','048','BD','fils',1000);
+INSERT INTO currency VALUES('bi','franc','BIF','108','FBu','centimes',100);
+INSERT INTO currency VALUES('bj','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('bm','dollar','BMD','060','Bd$','cents',100);
+INSERT INTO currency VALUES('bn','ringgit','BND','096','B$','sen',100);
+INSERT INTO currency VALUES('bo','boliviano','BOB','068','Bs','centavos',100);
+INSERT INTO currency VALUES('br','real','BRL','986','R$','centavos',100);
+INSERT INTO currency VALUES('bs','dollar','BSD','044','B$','cents',100);
+INSERT INTO currency VALUES('bt','ngultrum','BTN','064','Nu.','chhertum',100);
+INSERT INTO currency VALUES('bv','krone','NOK','578','NKr','Ore',100);
+INSERT INTO currency VALUES('bw','pula','BWP','072','P','thebe',100);
+INSERT INTO currency VALUES('by','ruble','BYR','112','BR','','');
+INSERT INTO currency VALUES('bz','dollar','BZD','084','BZ$','cents',100);
+INSERT INTO currency VALUES('ca','dollar','CAD','124','Can$','cents',100);
+INSERT INTO currency VALUES('cc','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('cd','franc','CDF','180','CFAF','centimes',100);
+INSERT INTO currency VALUES('cf','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('cg','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('ch','franc','CHF','756','SwF','centimes',100);
+INSERT INTO currency VALUES('ci','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('ck','dollar','NZD','554','NZ$','cents',100);
+INSERT INTO currency VALUES('cl','peso','CLP','152','Ch$','centavos',100);
+INSERT INTO currency VALUES('cm','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('cn','yuan renminbi','CNY','156','å
','jiao',10);
+INSERT INTO currency VALUES('co','peso','COP','170','Col$','centavos',100);
+INSERT INTO currency VALUES('cr','colon','CRC','188','â¡','centimos',100);
+INSERT INTO currency VALUES('cu','peso','CUP','192','Cu$','centavos',100);
+INSERT INTO currency VALUES('cv','escudo','CVE','132','C.V.Esc','centavos',100);
+INSERT INTO currency VALUES('cx','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('cy','pound','CYP','196','C','cents',100);
+INSERT INTO currency VALUES('cz','koruna','CZK','203','Kc','haleru',100);
+INSERT INTO currency VALUES('de','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('dj','franc','DJF','262','DF','centimes',100);
+INSERT INTO currency VALUES('dk','krone','DKK','208','Dkr','Ore',100);
+INSERT INTO currency VALUES('dm','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('do','peso','DOP','214','RD$','centavos',100);
+INSERT INTO currency VALUES('dz','dinar','DZD','012','DA','centimes',100);
+INSERT INTO currency VALUES('ec','sucre','ECS','218','S/','centavos',100);
+INSERT INTO currency VALUES('ee','kroon','EEK','233','KR','senti',100);
+INSERT INTO currency VALUES('eg','pound','EGP','818','E','piasters',100);
+INSERT INTO currency VALUES('eh','dirham','MAD','504','DH','centimes',100);
+INSERT INTO currency VALUES('er','nakfa','ERN','232','Nfa','cents',100);
+INSERT INTO currency VALUES('es','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('et','birr','ETB','230','Br','cents',100);
+INSERT INTO currency VALUES('fi','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('fj','dollar','FJD','242','F$','cents',100);
+INSERT INTO currency VALUES('fk','pound','FKP','238','F','pence',100);
+INSERT INTO currency VALUES('fm','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('fo','krone','DKK','208','DKr','Ore',100);
+INSERT INTO currency VALUES('fr','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('fx','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('ga','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('gb','pound','GBP','826','£','pence',100);
+INSERT INTO currency VALUES('gd','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('ge','lari','GEL','981','','tetri',100);
+INSERT INTO currency VALUES('gf','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('gh','new cedi','GHC','288','','psewas',100);
+INSERT INTO currency VALUES('gi','pound','GIP','292','G','pence',100);
+INSERT INTO currency VALUES('gl','krone','DKK','208','Dkr','Ore',100);
+INSERT INTO currency VALUES('gm','dalasi','GMD','270','D','butut',100);
+INSERT INTO currency VALUES('gn','franc','GNF','324','','','');
+INSERT INTO currency VALUES('gp','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('gq','franc','GQE','226','CFAF','centimos',100);
+INSERT INTO currency VALUES('gr','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('gs','pound','GBP','826',NULL,'pence',100);
+INSERT INTO currency VALUES('gt','quetzal','GTQ','320','Q','centavos',100);
+INSERT INTO currency VALUES('gu','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('gw','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('gy','dollar','GYD','328','G$','cents',100);
+INSERT INTO currency VALUES('hk','dollar','HKD','344','HK$','cents',100);
+INSERT INTO currency VALUES('hm','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('hn','lempira','HNL','340','L','centavos',100);
+INSERT INTO currency VALUES('hr','kuna','HRK','191','HRK','lipas',100);
+INSERT INTO currency VALUES('ht','gourde','HTG','332','G','centimes',100);
+INSERT INTO currency VALUES('hu','forint','HUF','348','Ft','','');
+INSERT INTO currency VALUES('id','rupiah','IDR','360','Rp','sen',100);
+INSERT INTO currency VALUES('ie','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('il','new sheqel','ILS','376','âª','new agorot',100);
+INSERT INTO currency VALUES('in','rupee','INR','356','Rs','paise',100);
+INSERT INTO currency VALUES('io','pound','GBP','826',NULL,'pence',100);
+INSERT INTO currency VALUES('iq','dinar','IQD','368','ID','fils',1000);
+INSERT INTO currency VALUES('ir','rial','IRR','364','Rls','','');
+INSERT INTO currency VALUES('is','krna','ISK','352','IKr','aurar',100);
+INSERT INTO currency VALUES('it','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('jm','dollar','JMD','388','J$','cents',100);
+INSERT INTO currency VALUES('jo','dinar','JOD','400','JD','fils',1000);
+INSERT INTO currency VALUES('jp','yen','JPY','392','','sen',100);
+INSERT INTO currency VALUES('ke','shilling','KES','404','K Sh','cents',100);
+INSERT INTO currency VALUES('kg','som','KGS','417','','tyyn',100);
+INSERT INTO currency VALUES('kh','new riel','KHR','116','CR','sen',100);
+INSERT INTO currency VALUES('ki','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('km','franc','KMF','174','CF','','');
+INSERT INTO currency VALUES('kn','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('kp','won','KPW','408','â©','chon',100);
+INSERT INTO currency VALUES('kr','won','KRW','410','â©','chon',100);
+INSERT INTO currency VALUES('kw','dinar','KWD','414','KD','fils',1000);
+INSERT INTO currency VALUES('ky','dollar','KYD','136','CI$','cents',100);
+INSERT INTO currency VALUES('kz','tenge','KZT','398','','tiyn',100);
+INSERT INTO currency VALUES('la','new kip','LAK','418','â','at',100);
+INSERT INTO currency VALUES('lb','pound','LBP','422','L.L.','piastres',100);
+INSERT INTO currency VALUES('lc','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('li','franc','CHF','756','SwF','centimes',100);
+INSERT INTO currency VALUES('lk','rupee','LKR','144','SLRs','cents',100);
+INSERT INTO currency VALUES('lr','dollar','LRD','430','$','cents',100);
+INSERT INTO currency VALUES('ls','loti','LSL','426','L','lisente',100);
+INSERT INTO currency VALUES('lt','litas','LTL','440','','centu',100);
+INSERT INTO currency VALUES('lu','Euro','EUR','978','','cents',100);
+INSERT INTO currency VALUES('lv','lat','LVL','428','Ls','santims',100);
+INSERT INTO currency VALUES('ly','dinar','LYD','434','LD','dirhams',1000);
+INSERT INTO currency VALUES('ma','dirham','MAD','504','DH','centimes',100);
+INSERT INTO currency VALUES('mc','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('md','leu','MDL','498',NULL,NULL,NULL);
+INSERT INTO currency VALUES('mg','ariayry','MGF','450','FMG','francs',5);
+INSERT INTO currency VALUES('mh','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('mk','denar','MKD','807','MKD','deni',100);
+INSERT INTO currency VALUES('ml','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('mm','kyat','MMK','104','K','pyas',100);
+INSERT INTO currency VALUES('mn','tögrög','MNT','496','â®','möngö',100);
+INSERT INTO currency VALUES('mo','pataca','MOP','446','P','avos',100);
+INSERT INTO currency VALUES('mp','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('mq','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('mr','ouguiya','MRO','478','UM','khoums',5);
+INSERT INTO currency VALUES('ms','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('mt','lira','MTL','470','Lm','cents',100);
+INSERT INTO currency VALUES('mu','rupee','MUR','480','Mau Rs','cents',100);
+INSERT INTO currency VALUES('mv','rufiyaa','MVR','462','Rf','lari',100);
+INSERT INTO currency VALUES('mw','kwacha','MWK','454','MK','tambala',100);
+INSERT INTO currency VALUES('mx','peso','MXN','484','Mex$','centavos',100);
+INSERT INTO currency VALUES('my','ringgit','MYR','458','RM','sen',100);
+INSERT INTO currency VALUES('mz','metical','MZM','508','Mt','centavos',100);
+INSERT INTO currency VALUES('na','dollar','NAD','516','N$','cents',100);
+INSERT INTO currency VALUES('nc','franc','XPF','953','CFPF','centimes',100);
+INSERT INTO currency VALUES('ne','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('nf','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('ng','naira','NGN','566','â¦','kobo',100);
+INSERT INTO currency VALUES('ni','gold cordoba','NIO','558','C$','centavos',100);
+INSERT INTO currency VALUES('nl','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('no','krone','NOK','578','NKr','Ore',100);
+INSERT INTO currency VALUES('np','rupee','NPR','524','NRs','paise',100);
+INSERT INTO currency VALUES('nr','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('nu','dollar','NZD','554','NZ$','cents',100);
+INSERT INTO currency VALUES('nz','dollar','NZD','554','NZ$','cents',100);
+INSERT INTO currency VALUES('om','rial','OMR','512','RO','baizas',1000);
+INSERT INTO currency VALUES('pa','balboa','PAB','590','B','centesimos',100);
+INSERT INTO currency VALUES('pe','nuevo sol','PEN','604','S/.','centimos',100);
+INSERT INTO currency VALUES('pf','franc','XPF','953','CFPF','centimes',100);
+INSERT INTO currency VALUES('pg','kina','PGK','598','K','toeas',100);
+INSERT INTO currency VALUES('ph','peso','PHP','608','â±','centavos',100);
+INSERT INTO currency VALUES('pk','rupee','PKR','586','Rs','paisa',100);
+INSERT INTO currency VALUES('pl','zloty','PLN','985','zÅ','groszy',100);
+INSERT INTO currency VALUES('pm','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('pn','dollar','NZD','554','NZ$','cents',100);
+INSERT INTO currency VALUES('pr','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('ps','new shekel','ILS','376','NIS','new agorot',100);
+INSERT INTO currency VALUES('pt','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('pw','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('py','guarani','PYG','600','G.','centimos',100);
+INSERT INTO currency VALUES('qa','riyal','QAR','634','QR','dirhams',100);
+INSERT INTO currency VALUES('re','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('ro','leu','ROL','642','L','bani',100);
+INSERT INTO currency VALUES('ru','ruble','RUB','810','ÑÑб','kopecks',100);
+INSERT INTO currency VALUES('rw','franc','RWF','646','RF','centimes',100);
+INSERT INTO currency VALUES('sa','riyal','SAR','682','SRls','halalat',100);
+INSERT INTO currency VALUES('sb','dollar','SBD','090','SI$','cents',100);
+INSERT INTO currency VALUES('sc','rupee','SCR','690','SR','cents',100);
+INSERT INTO currency VALUES('sd','dinar','SDP','736','','piastres',100);
+INSERT INTO currency VALUES('se','krona','SEK','752','Sk','Ore',100);
+INSERT INTO currency VALUES('sg','dollar','SGD','702','S$','cents',100);
+INSERT INTO currency VALUES('sh','pound','SHP','654','S','new pence',100);
+INSERT INTO currency VALUES('si','tolar','SIT','705','SlT','stotinov',100);
+INSERT INTO currency VALUES('sj','krone','NOK','578','NKr','Ore',100);
+INSERT INTO currency VALUES('sk','koruna','SKK','703','Sk','halierov',100);
+INSERT INTO currency VALUES('sl','leone','SLL','694','Le','cents',100);
+INSERT INTO currency VALUES('sm','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('sn','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('so','shilling','SOS','706','So. Sh.','centesimi',100);
+INSERT INTO currency VALUES('sr','guilder','SRG','740','Sf.','cents',100);
+INSERT INTO currency VALUES('st','dobra','STD','678','Db','centimos',100);
+INSERT INTO currency VALUES('sv','colon','SVC','222','','centavos',100);
+INSERT INTO currency VALUES('sy','pound','SYP','760','S','piasters',100);
+INSERT INTO currency VALUES('sz','lilangeni','SZL','748','L','cents',100);
+INSERT INTO currency VALUES('tc','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('td','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('tf','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('tg','franc','XOF','952','CFAF','centimes',100);
+INSERT INTO currency VALUES('th','baht','THB','764','฿','stang',100);
+INSERT INTO currency VALUES('tj','somoni','TJS','762','','dirams',100);
+INSERT INTO currency VALUES('tk','dollar','NZD','554','NZ$','cents',100);
+INSERT INTO currency VALUES('tl','rupiah','IDR','360','Rp','sen',100);
+INSERT INTO currency VALUES('tm','manat','TMM','795','','tenga',100);
+INSERT INTO currency VALUES('tn','dinar','TND','788','TD','millimes',1000);
+INSERT INTO currency VALUES('to','pa''anga','TOP','776','PT or T$','seniti',100);
+INSERT INTO currency VALUES('tr','lira','TRL','792','TL','kurus',100);
+INSERT INTO currency VALUES('tt','dollar','TTD','780','TT$','cents',100);
+INSERT INTO currency VALUES('tv','dollar','AUD','036','A$','cents',100);
+INSERT INTO currency VALUES('tw','new dollar','TWD','901','NT$','cents',100);
+INSERT INTO currency VALUES('tz','shilling','TZS','834','TSh','cents',100);
+INSERT INTO currency VALUES('ua','Hryvnia','UAH','980','','kopiykas',100);
+INSERT INTO currency VALUES('ug','shilling','UGX','800','USh','cents',100);
+INSERT INTO currency VALUES('um','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('us','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('uy','peso uruguayo','UYU','858','$U','centsimos',100);
+INSERT INTO currency VALUES('uz','som','UZS','860','','tiyin',100);
+INSERT INTO currency VALUES('va','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('vc','dollar','XCD','951','EC$','cents',100);
+INSERT INTO currency VALUES('ve','bolivar','VEB','862','Bs','centimos',100);
+INSERT INTO currency VALUES('vg','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('vi','dollar','USD','840','$','cents',100);
+INSERT INTO currency VALUES('vn','Äá»ng','VND','704','â«','hà o',10);
+INSERT INTO currency VALUES('vu','vatu','VUV','548','VT','centimes',100);
+INSERT INTO currency VALUES('wf','franc','XPF','953','CFPF','centimes',100);
+INSERT INTO currency VALUES('ws','tala','WST','882','WS$','sene',100);
+INSERT INTO currency VALUES('ye','rial','YER','886','YRls','fils',100);
+INSERT INTO currency VALUES('yt','Euro','EUR','978','â¬','cents',100);
+INSERT INTO currency VALUES('yu','dinar','YUM','891','Din','paras',100);
+INSERT INTO currency VALUES('za','rand','ZAR','710','R','cents',100);
+INSERT INTO currency VALUES('zm','kwacha','ZMK','894','ZK','ngwee',100);
+INSERT INTO currency VALUES('zr','franc','XAF','950','CFAF','centimes',100);
+INSERT INTO currency VALUES('zw','dollar','ZWD','716','Z$','cents',100);
+CREATE TABLE language (
+ code_alpha2 char(2),
+ code_alpha3 char(3),
+ name char(100),
+ PRIMARY KEY (code_alpha3)
+);
+INSERT INTO language VALUES('ab','abk','Abkhazian');
+INSERT INTO language VALUES(NULL,'ace','Achinese');
+INSERT INTO language VALUES(NULL,'ach','Acoli');
+INSERT INTO language VALUES(NULL,'ada','Adangme');
+INSERT INTO language VALUES('aa','aar','Afar');
+INSERT INTO language VALUES(NULL,'afh','Afrihili');
+INSERT INTO language VALUES('af','afr','Afrikaans');
+INSERT INTO language VALUES(NULL,'afa','Afro-Asiatic (Other)');
+INSERT INTO language VALUES(NULL,'aka','Akan');
+INSERT INTO language VALUES(NULL,'akk','Akkadian');
+INSERT INTO language VALUES('sq','sqi','Albanian');
+INSERT INTO language VALUES(NULL,'ale','Aleut');
+INSERT INTO language VALUES(NULL,'alg','Algonquian languages');
+INSERT INTO language VALUES(NULL,'tut','Altaic (Other)');
+INSERT INTO language VALUES('am','amh','Amharic');
+INSERT INTO language VALUES(NULL,'apa','Apache languages');
+INSERT INTO language VALUES('ar','ara','Arabic');
+INSERT INTO language VALUES(NULL,'arc','Aramaic');
+INSERT INTO language VALUES(NULL,'arp','Arapaho');
+INSERT INTO language VALUES(NULL,'arn','Araucanian');
+INSERT INTO language VALUES(NULL,'arw','Arawak');
+INSERT INTO language VALUES('hy','hye','Armenian');
+INSERT INTO language VALUES(NULL,'art','Artificial (Other)');
+INSERT INTO language VALUES('as','asm','Assamese');
+INSERT INTO language VALUES(NULL,'ath','Athapascan languages');
+INSERT INTO language VALUES(NULL,'map','Austronesian (Other)');
+INSERT INTO language VALUES(NULL,'ava','Avaric');
+INSERT INTO language VALUES(NULL,'ave','Avestan');
+INSERT INTO language VALUES(NULL,'awa','Awadhi');
+INSERT INTO language VALUES('ay','aym','Aymara');
+INSERT INTO language VALUES('az','aze','Azerbaijani');
+INSERT INTO language VALUES(NULL,'nah','Aztec');
+INSERT INTO language VALUES(NULL,'ban','Balinese');
+INSERT INTO language VALUES(NULL,'bat','Baltic (Other)');
+INSERT INTO language VALUES(NULL,'bal','Baluchi');
+INSERT INTO language VALUES(NULL,'bam','Bambara');
+INSERT INTO language VALUES(NULL,'bai','Bamileke languages');
+INSERT INTO language VALUES(NULL,'bad','Banda');
+INSERT INTO language VALUES(NULL,'bnt','Bantu (Other)');
+INSERT INTO language VALUES(NULL,'bas','Basa');
+INSERT INTO language VALUES('ba','bak','Bashkir');
+INSERT INTO language VALUES('eu','eus','Basque');
+INSERT INTO language VALUES(NULL,'bej','Beja');
+INSERT INTO language VALUES(NULL,'bem','Bemba');
+INSERT INTO language VALUES('bn','ben','Bengali');
+INSERT INTO language VALUES(NULL,'ber','Berber (Other)');
+INSERT INTO language VALUES(NULL,'bho','Bhojpuri');
+INSERT INTO language VALUES('bh','bih','Bihari');
+INSERT INTO language VALUES(NULL,'bik','Bikol');
+INSERT INTO language VALUES(NULL,'bin','Bini');
+INSERT INTO language VALUES('bi','bis','Bislama');
+INSERT INTO language VALUES(NULL,'bra','Braj');
+INSERT INTO language VALUES('br','bre','Breton');
+INSERT INTO language VALUES(NULL,'bug','Buginese');
+INSERT INTO language VALUES('bg','bul','Bulgarian');
+INSERT INTO language VALUES(NULL,'bua','Buriat');
+INSERT INTO language VALUES('my','mya','Burmese');
+INSERT INTO language VALUES('be','bel','Byelorussian');
+INSERT INTO language VALUES(NULL,'cad','Caddo');
+INSERT INTO language VALUES(NULL,'car','Carib');
+INSERT INTO language VALUES('ca','cat','Catalan');
+INSERT INTO language VALUES(NULL,'cau','Caucasian (Other)');
+INSERT INTO language VALUES(NULL,'ceb','Cebuano');
+INSERT INTO language VALUES(NULL,'cel','Celtic (Other)');
+INSERT INTO language VALUES(NULL,'cai','Central American Indian (Other)');
+INSERT INTO language VALUES(NULL,'chg','Chagatai');
+INSERT INTO language VALUES(NULL,'cha','Chamorro');
+INSERT INTO language VALUES(NULL,'che','Chechen');
+INSERT INTO language VALUES(NULL,'chr','Cherokee');
+INSERT INTO language VALUES(NULL,'chy','Cheyenne');
+INSERT INTO language VALUES(NULL,'chb','Chibcha');
+INSERT INTO language VALUES('zh','zho','Chinese');
+INSERT INTO language VALUES(NULL,'chn','Chinook jargon');
+INSERT INTO language VALUES(NULL,'cho','Choctaw');
+INSERT INTO language VALUES(NULL,'chu','Church Slavic');
+INSERT INTO language VALUES(NULL,'chv','Chuvash');
+INSERT INTO language VALUES(NULL,'cop','Coptic');
+INSERT INTO language VALUES(NULL,'cor','Cornish');
+INSERT INTO language VALUES('co','cos','Corsican');
+INSERT INTO language VALUES(NULL,'cre','Cree');
+INSERT INTO language VALUES(NULL,'mus','Creek');
+INSERT INTO language VALUES(NULL,'crp','Creoles and Pidgins (Other)');
+INSERT INTO language VALUES(NULL,'cpe','Creoles and Pidgins, English-based (Other)');
+INSERT INTO language VALUES(NULL,'cpf','Creoles and Pidgins, French-based (Other)');
+INSERT INTO language VALUES(NULL,'cpp','Creoles and Pidgins, Portuguese-based (Other)');
+INSERT INTO language VALUES(NULL,'cus','Cushitic (Other)');
+INSERT INTO language VALUES('hr','hrv','Croatian');
+INSERT INTO language VALUES('cs','cze','Czech');
+INSERT INTO language VALUES(NULL,'dak','Dakota');
+INSERT INTO language VALUES('da','dan','Danish');
+INSERT INTO language VALUES(NULL,'del','Delaware');
+INSERT INTO language VALUES(NULL,'din','Dinka');
+INSERT INTO language VALUES(NULL,'div','Divehi');
+INSERT INTO language VALUES(NULL,'doi','Dogri');
+INSERT INTO language VALUES(NULL,'dra','Dravidian (Other)');
+INSERT INTO language VALUES(NULL,'dua','Duala');
+INSERT INTO language VALUES('nl','nla','Dutch');
+INSERT INTO language VALUES(NULL,'dum','Dutch, Middle (ca. 1050-1350)');
+INSERT INTO language VALUES(NULL,'dyu','Dyula');
+INSERT INTO language VALUES('dz','dzo','Dzongkha');
+INSERT INTO language VALUES(NULL,'efi','Efik');
+INSERT INTO language VALUES(NULL,'egy','Egyptian (Ancient)');
+INSERT INTO language VALUES(NULL,'eka','Ekajuk');
+INSERT INTO language VALUES(NULL,'elx','Elamite');
+INSERT INTO language VALUES('en','eng','English');
+INSERT INTO language VALUES(NULL,'enm','English, Middle (ca. 1100-1500)');
+INSERT INTO language VALUES(NULL,'ang','English, Old (ca. 450-1100)');
+INSERT INTO language VALUES(NULL,'esk','Eskimo (Other)');
+INSERT INTO language VALUES('eo','epo','Esperanto');
+INSERT INTO language VALUES('et','est','Estonian');
+INSERT INTO language VALUES(NULL,'ewe','Ewe');
+INSERT INTO language VALUES(NULL,'ewo','Ewondo');
+INSERT INTO language VALUES(NULL,'fan','Fang');
+INSERT INTO language VALUES(NULL,'fat','Fanti');
+INSERT INTO language VALUES('fo','fao','Faroese');
+INSERT INTO language VALUES('fj','fij','Fijian');
+INSERT INTO language VALUES('fi','fin','Finnish');
+INSERT INTO language VALUES(NULL,'fiu','Finno-Ugrian (Other)');
+INSERT INTO language VALUES(NULL,'fon','Fon');
+INSERT INTO language VALUES('fr','fre','French');
+INSERT INTO language VALUES(NULL,'frm','French, Middle (ca. 1400-1600)');
+INSERT INTO language VALUES(NULL,'fro','French, Old (842- ca. 1400)');
+INSERT INTO language VALUES('fy','fry','Frisian');
+INSERT INTO language VALUES(NULL,'ful','Fulah');
+INSERT INTO language VALUES(NULL,'gaa','Ga');
+INSERT INTO language VALUES(NULL,'gae','Gaelic (Scots)');
+INSERT INTO language VALUES('gl','glg','Gallegan');
+INSERT INTO language VALUES(NULL,'lug','Ganda');
+INSERT INTO language VALUES(NULL,'gay','Gayo');
+INSERT INTO language VALUES(NULL,'gez','Geez');
+INSERT INTO language VALUES('ka','kat','Georgian');
+INSERT INTO language VALUES('de','ger','German');
+INSERT INTO language VALUES(NULL,'gmh','German, Middle High (ca. 1050-1500)');
+INSERT INTO language VALUES(NULL,'goh','German, Old High (ca. 750-1050)');
+INSERT INTO language VALUES(NULL,'gem','Germanic (Other)');
+INSERT INTO language VALUES(NULL,'gil','Gilbertese');
+INSERT INTO language VALUES(NULL,'gon','Gondi');
+INSERT INTO language VALUES(NULL,'got','Gothic');
+INSERT INTO language VALUES(NULL,'grb','Grebo');
+INSERT INTO language VALUES(NULL,'grc','Greek, Ancient (to 1453)');
+INSERT INTO language VALUES('el','gre','Greek');
+INSERT INTO language VALUES('kl','kal','Greenlandic');
+INSERT INTO language VALUES('gn','grn','Guarani');
+INSERT INTO language VALUES('gu','guj','Gujarati');
+INSERT INTO language VALUES(NULL,'hai','Haida');
+INSERT INTO language VALUES('ha','hau','Hausa');
+INSERT INTO language VALUES(NULL,'haw','Hawaiian');
+INSERT INTO language VALUES('he','heb','Hebrew');
+INSERT INTO language VALUES(NULL,'her','Herero');
+INSERT INTO language VALUES(NULL,'hil','Hiligaynon');
+INSERT INTO language VALUES(NULL,'him','Himachali');
+INSERT INTO language VALUES('hi','hin','Hindi');
+INSERT INTO language VALUES(NULL,'hmo','Hiri Motu');
+INSERT INTO language VALUES('hu','hun','Hungarian');
+INSERT INTO language VALUES(NULL,'hup','Hupa');
+INSERT INTO language VALUES(NULL,'iba','Iban');
+INSERT INTO language VALUES('is','isl','Icelandic');
+INSERT INTO language VALUES(NULL,'ibo','Igbo');
+INSERT INTO language VALUES(NULL,'ijo','Ijo');
+INSERT INTO language VALUES(NULL,'ilo','Iloko');
+INSERT INTO language VALUES(NULL,'inc','Indic (Other)');
+INSERT INTO language VALUES(NULL,'ine','Indo-European (Other)');
+INSERT INTO language VALUES('id','ind','Indonesian');
+INSERT INTO language VALUES('ia','ina','Interlingua (International Auxiliary language Association)');
+INSERT INTO language VALUES('iu','iku','Inuktitut');
+INSERT INTO language VALUES('ik','ipk','Inupiak');
+INSERT INTO language VALUES(NULL,'ira','Iranian (Other)');
+INSERT INTO language VALUES('ga','iri','Irish');
+INSERT INTO language VALUES(NULL,'sga','Irish, Old (to 900)');
+INSERT INTO language VALUES(NULL,'mga','Irish, Middle (900 - 1200)');
+INSERT INTO language VALUES(NULL,'iro','Iroquoian languages');
+INSERT INTO language VALUES('it','ita','Italian');
+INSERT INTO language VALUES('ja','jpn','Japanese');
+INSERT INTO language VALUES('jv','jaw','Javanese');
+INSERT INTO language VALUES(NULL,'jrb','Judeo-Arabic');
+INSERT INTO language VALUES(NULL,'jpr','Judeo-Persian');
+INSERT INTO language VALUES(NULL,'kab','Kabyle');
+INSERT INTO language VALUES(NULL,'kac','Kachin');
+INSERT INTO language VALUES(NULL,'kam','Kamba');
+INSERT INTO language VALUES('kn','kan','Kannada');
+INSERT INTO language VALUES(NULL,'kau','Kanuri');
+INSERT INTO language VALUES(NULL,'kaa','Kara-Kalpak');
+INSERT INTO language VALUES(NULL,'kar','Karen');
+INSERT INTO language VALUES('ks','kas','Kashmiri');
+INSERT INTO language VALUES(NULL,'kaw','Kawi');
+INSERT INTO language VALUES('kk','kaz','Kazakh');
+INSERT INTO language VALUES(NULL,'kha','Khasi');
+INSERT INTO language VALUES('km','khm','Khmer');
+INSERT INTO language VALUES(NULL,'khi','Khoisan (Other)');
+INSERT INTO language VALUES(NULL,'kho','Khotanese');
+INSERT INTO language VALUES(NULL,'kik','Kikuyu');
+INSERT INTO language VALUES('rw','kin','Kinyarwanda');
+INSERT INTO language VALUES('ky','kir','Kirghiz');
+INSERT INTO language VALUES(NULL,'kom','Komi');
+INSERT INTO language VALUES(NULL,'kon','Kongo');
+INSERT INTO language VALUES(NULL,'kok','Konkani');
+INSERT INTO language VALUES('ko','kor','Korean');
+INSERT INTO language VALUES(NULL,'kpe','Kpelle');
+INSERT INTO language VALUES(NULL,'kro','Kru');
+INSERT INTO language VALUES(NULL,'kua','Kuanyama');
+INSERT INTO language VALUES(NULL,'kum','Kumyk');
+INSERT INTO language VALUES('ku','kur','Kurdish');
+INSERT INTO language VALUES(NULL,'kru','Kurukh');
+INSERT INTO language VALUES(NULL,'kus','Kusaie');
+INSERT INTO language VALUES(NULL,'kut','Kutenai');
+INSERT INTO language VALUES(NULL,'lad','Ladino');
+INSERT INTO language VALUES(NULL,'lah','Lahnda');
+INSERT INTO language VALUES(NULL,'lam','Lamba');
+INSERT INTO language VALUES('oc','oci','Langue d''Oc (post 1500)');
+INSERT INTO language VALUES('lo','lao','Lao');
+INSERT INTO language VALUES('la','lat','Latin');
+INSERT INTO language VALUES('lv','lav','Latvian');
+INSERT INTO language VALUES(NULL,'ltz','Letzeburgesch');
+INSERT INTO language VALUES(NULL,'lez','Lezghian');
+INSERT INTO language VALUES('ln','lin','Lingala');
+INSERT INTO language VALUES('lt','lit','Lithuanian');
+INSERT INTO language VALUES(NULL,'loz','Lozi');
+INSERT INTO language VALUES(NULL,'lub','Luba-Katanga');
+INSERT INTO language VALUES(NULL,'lui','Luiseno');
+INSERT INTO language VALUES(NULL,'lun','Lunda');
+INSERT INTO language VALUES(NULL,'luo','Luo (Kenya and Tanzania)');
+INSERT INTO language VALUES('mk','mak','Macedonian');
+INSERT INTO language VALUES(NULL,'mad','Madurese');
+INSERT INTO language VALUES(NULL,'mag','Magahi');
+INSERT INTO language VALUES(NULL,'mai','Maithili');
+INSERT INTO language VALUES(NULL,'mkd','Makasar');
+INSERT INTO language VALUES('mg','mlg','Malagasy');
+INSERT INTO language VALUES('ms','msa','Malay');
+INSERT INTO language VALUES(NULL,'mal','Malayalam');
+INSERT INTO language VALUES('ml','mlt','Maltese');
+INSERT INTO language VALUES(NULL,'man','Mandingo');
+INSERT INTO language VALUES(NULL,'mni','Manipuri');
+INSERT INTO language VALUES(NULL,'mno','Manobo languages');
+INSERT INTO language VALUES(NULL,'max','Manx');
+INSERT INTO language VALUES('mi','mri','Maori');
+INSERT INTO language VALUES('mr','mar','Marathi');
+INSERT INTO language VALUES(NULL,'chm','Mari');
+INSERT INTO language VALUES(NULL,'mah','Marshall');
+INSERT INTO language VALUES(NULL,'mwr','Marwari');
+INSERT INTO language VALUES(NULL,'mas','Masai');
+INSERT INTO language VALUES(NULL,'myn','Mayan languages');
+INSERT INTO language VALUES(NULL,'men','Mende');
+INSERT INTO language VALUES(NULL,'mic','Micmac');
+INSERT INTO language VALUES(NULL,'min','Minangkabau');
+INSERT INTO language VALUES(NULL,'mis','Miscellaneous (Other)');
+INSERT INTO language VALUES(NULL,'moh','Mohawk');
+INSERT INTO language VALUES('mo','mol','Moldavian');
+INSERT INTO language VALUES(NULL,'mkh','Mon-Kmer (Other)');
+INSERT INTO language VALUES(NULL,'lol','Mongo');
+INSERT INTO language VALUES('mn','mon','Mongolian');
+INSERT INTO language VALUES(NULL,'mos','Mossi');
+INSERT INTO language VALUES(NULL,'mul','Multiple languages');
+INSERT INTO language VALUES(NULL,'mun','Munda languages');
+INSERT INTO language VALUES('na','nau','Nauru');
+INSERT INTO language VALUES(NULL,'nav','Navajo');
+INSERT INTO language VALUES(NULL,'nde','Ndebele, North');
+INSERT INTO language VALUES(NULL,'nbl','Ndebele, South');
+INSERT INTO language VALUES(NULL,'ndo','Ndongo');
+INSERT INTO language VALUES('ne','nep','Nepali');
+INSERT INTO language VALUES(NULL,'new','Newari');
+INSERT INTO language VALUES(NULL,'nic','Niger-Kordofanian (Other)');
+INSERT INTO language VALUES(NULL,'ssa','Nilo-Saharan (Other)');
+INSERT INTO language VALUES(NULL,'niu','Niuean');
+INSERT INTO language VALUES(NULL,'non','Norse, Old');
+INSERT INTO language VALUES(NULL,'nai','North American Indian (Other)');
+INSERT INTO language VALUES('no','nor','Norwegian');
+INSERT INTO language VALUES(NULL,'nno','Norwegian (Nynorsk)');
+INSERT INTO language VALUES(NULL,'nub','Nubian languages');
+INSERT INTO language VALUES(NULL,'nym','Nyamwezi');
+INSERT INTO language VALUES(NULL,'nya','Nyanja');
+INSERT INTO language VALUES(NULL,'nyn','Nyankole');
+INSERT INTO language VALUES(NULL,'nyo','Nyoro');
+INSERT INTO language VALUES(NULL,'nzi','Nzima');
+INSERT INTO language VALUES(NULL,'oji','Ojibwa');
+INSERT INTO language VALUES('or','ori','Oriya');
+INSERT INTO language VALUES('om','orm','Oromo');
+INSERT INTO language VALUES(NULL,'osa','Osage');
+INSERT INTO language VALUES(NULL,'oss','Ossetic');
+INSERT INTO language VALUES(NULL,'oto','Otomian languages');
+INSERT INTO language VALUES(NULL,'pal','Pahlavi');
+INSERT INTO language VALUES(NULL,'pau','Palauan');
+INSERT INTO language VALUES(NULL,'pli','Pali');
+INSERT INTO language VALUES(NULL,'pam','Pampanga');
+INSERT INTO language VALUES(NULL,'pag','Pangasinan');
+INSERT INTO language VALUES('pa','pan','Panjabi');
+INSERT INTO language VALUES(NULL,'pap','Papiamento');
+INSERT INTO language VALUES(NULL,'paa','Papuan-Australian (Other)');
+INSERT INTO language VALUES('fa','per','Persian');
+INSERT INTO language VALUES(NULL,'peo','Persian, Old (ca 600 - 400 B.C.)');
+INSERT INTO language VALUES(NULL,'phn','Phoenician');
+INSERT INTO language VALUES('pl','pol','Polish');
+INSERT INTO language VALUES(NULL,'pon','Ponape');
+INSERT INTO language VALUES('pt','por','Portuguese');
+INSERT INTO language VALUES(NULL,'pra','Prakrit languages');
+INSERT INTO language VALUES(NULL,'pro','Provencal, Old (to 1500)');
+INSERT INTO language VALUES('ps','pus','Pushto');
+INSERT INTO language VALUES('qu','que','Quechua');
+INSERT INTO language VALUES('rm','roh','Rhaeto-Romance');
+INSERT INTO language VALUES(NULL,'raj','Rajasthani');
+INSERT INTO language VALUES(NULL,'rar','Rarotongan');
+INSERT INTO language VALUES(NULL,'roa','Romance (Other)');
+INSERT INTO language VALUES('ro','rum','Romanian');
+INSERT INTO language VALUES(NULL,'rom','Romany');
+INSERT INTO language VALUES('rn','run','Rundi');
+INSERT INTO language VALUES('ru','rus','Russian');
+INSERT INTO language VALUES(NULL,'sal','Salishan languages');
+INSERT INTO language VALUES(NULL,'sam','Samaritan Aramaic');
+INSERT INTO language VALUES(NULL,'smi','Sami languages');
+INSERT INTO language VALUES('sm','smo','Samoan');
+INSERT INTO language VALUES(NULL,'sad','Sandawe');
+INSERT INTO language VALUES('sg','sag','Sango');
+INSERT INTO language VALUES('sa','san','Sanskrit');
+INSERT INTO language VALUES(NULL,'srd','Sardinian');
+INSERT INTO language VALUES(NULL,'sco','Scots');
+INSERT INTO language VALUES(NULL,'sel','Selkup');
+INSERT INTO language VALUES(NULL,'sem','Semitic (Other)');
+INSERT INTO language VALUES('sr','srp','Serbian');
+INSERT INTO language VALUES('sh','scr','Serbo-Croatian');
+INSERT INTO language VALUES(NULL,'srr','Serer');
+INSERT INTO language VALUES(NULL,'shn','Shan');
+INSERT INTO language VALUES('sn','sna','Shona');
+INSERT INTO language VALUES(NULL,'sid','Sidamo');
+INSERT INTO language VALUES(NULL,'bla','Siksika');
+INSERT INTO language VALUES('sd','snd','Sindhi');
+INSERT INTO language VALUES('si','sin','Singhalese');
+INSERT INTO language VALUES(NULL,'sit','Sino-Tibetan (Other)');
+INSERT INTO language VALUES(NULL,'sio','Siouan languages');
+INSERT INTO language VALUES(NULL,'sla','Slavic (Other)');
+INSERT INTO language VALUES('sk','slo','Slovak');
+INSERT INTO language VALUES('sl','slv','Slovenian');
+INSERT INTO language VALUES(NULL,'sog','Sogdian');
+INSERT INTO language VALUES('so','som','Somali');
+INSERT INTO language VALUES(NULL,'son','Songhai');
+INSERT INTO language VALUES(NULL,'wen','Sorbian languages');
+INSERT INTO language VALUES(NULL,'nso','Sotho, Northern');
+INSERT INTO language VALUES('st','sot','Sotho, Southern');
+INSERT INTO language VALUES(NULL,'sai','South American Indian (Other)');
+INSERT INTO language VALUES('es','spa','Spanish');
+INSERT INTO language VALUES(NULL,'suk','Sukuma');
+INSERT INTO language VALUES(NULL,'sux','Sumerian');
+INSERT INTO language VALUES('su','sun','Sudanese');
+INSERT INTO language VALUES(NULL,'sus','Susu');
+INSERT INTO language VALUES('sw','swa','Swahili');
+INSERT INTO language VALUES(NULL,'ssw','Swazi');
+INSERT INTO language VALUES('sv','sve','Swedish');
+INSERT INTO language VALUES(NULL,'syr','Syriac');
+INSERT INTO language VALUES('tl','tgl','Tagalog');
+INSERT INTO language VALUES(NULL,'tah','Tahitian');
+INSERT INTO language VALUES('tg','tgk','Tajik');
+INSERT INTO language VALUES(NULL,'tmh','Tamashek');
+INSERT INTO language VALUES('ta','tam','Tamil');
+INSERT INTO language VALUES('tt','tat','Tatar');
+INSERT INTO language VALUES('te','tel','Telugu');
+INSERT INTO language VALUES(NULL,'ter','Tereno');
+INSERT INTO language VALUES(NULL,'tet','Tetum');
+INSERT INTO language VALUES('th','tha','Thai');
+INSERT INTO language VALUES('bo','tib','Tibetan');
+INSERT INTO language VALUES(NULL,'tig','Tigre');
+INSERT INTO language VALUES('ti','tir','Tigrinya');
+INSERT INTO language VALUES(NULL,'tem','Timne');
+INSERT INTO language VALUES(NULL,'tiv','Tivi');
+INSERT INTO language VALUES(NULL,'tli','Tlingit');
+INSERT INTO language VALUES('to','tog','Tonga (Nyasa)');
+INSERT INTO language VALUES(NULL,'ton','Tonga (Tonga Islands)');
+INSERT INTO language VALUES(NULL,'tru','Truk');
+INSERT INTO language VALUES(NULL,'tsi','Tsimshian');
+INSERT INTO language VALUES('ts','tso','Tsonga');
+INSERT INTO language VALUES('tn','tsn','Tswana');
+INSERT INTO language VALUES(NULL,'tum','Tumbuka');
+INSERT INTO language VALUES('tr','tur','Turkish');
+INSERT INTO language VALUES(NULL,'ota','Turkish, Ottoman (1500 - 1928)');
+INSERT INTO language VALUES('tk','tuk','Turkmen');
+INSERT INTO language VALUES(NULL,'tyv','Tuvinian');
+INSERT INTO language VALUES('tw','twi','Twi');
+INSERT INTO language VALUES(NULL,'uga','Ugaritic');
+INSERT INTO language VALUES('ug','uig','Uighur');
+INSERT INTO language VALUES('uk','ukr','Ukrainian');
+INSERT INTO language VALUES(NULL,'umb','Umbundu');
+INSERT INTO language VALUES(NULL,'und','Undetermined');
+INSERT INTO language VALUES('ur','urd','Urdu');
+INSERT INTO language VALUES('uz','uzb','Uzbek');
+INSERT INTO language VALUES(NULL,'vai','Vai');
+INSERT INTO language VALUES(NULL,'ven','Venda');
+INSERT INTO language VALUES('vi','vie','Vietnamese');
+INSERT INTO language VALUES('vo','vol','Volapuk');
+INSERT INTO language VALUES(NULL,'vot','Votic');
+INSERT INTO language VALUES(NULL,'wak','Wakashan languages');
+INSERT INTO language VALUES(NULL,'wal','Walamo');
+INSERT INTO language VALUES(NULL,'war','Waray');
+INSERT INTO language VALUES(NULL,'was','Washo');
+INSERT INTO language VALUES('cy','wel','Welsh');
+INSERT INTO language VALUES('wo','wol','Wolof');
+INSERT INTO language VALUES('xh','xho','Xhosa');
+INSERT INTO language VALUES(NULL,'sah','Yakut');
+INSERT INTO language VALUES(NULL,'yao','Yao');
+INSERT INTO language VALUES(NULL,'yap','Yap');
+INSERT INTO language VALUES('yi','yid','Yiddish');
+INSERT INTO language VALUES('yo','yor','Yoruba');
+INSERT INTO language VALUES(NULL,'zap','Zapotec');
+INSERT INTO language VALUES(NULL,'zen','Zenaga');
+INSERT INTO language VALUES('za','zha','Zhuang');
+INSERT INTO language VALUES('zu','zul','Zulu');
+INSERT INTO language VALUES(NULL,'zun','Zuni');
+INSERT INTO language VALUES(NULL,'tvl','Tuvalu');
+CREATE TABLE language_mappings (
+ id char(4),
+ country char(2),
+ language char(3),
+ official boolean,
+ PRIMARY KEY (id)
+);
+INSERT INTO language_mappings VALUES('af_0','af','pus','true');
+INSERT INTO language_mappings VALUES('af_1','af','per','false');
+INSERT INTO language_mappings VALUES('al_0','al','sqi','true');
+INSERT INTO language_mappings VALUES('al_1','al','gre','false');
+INSERT INTO language_mappings VALUES('dz_0','dz','ara','true');
+INSERT INTO language_mappings VALUES('dz_1','dz','fre','false');
+INSERT INTO language_mappings VALUES('ad_0','ad','cat','true');
+INSERT INTO language_mappings VALUES('ad_1','ad','fre','false');
+INSERT INTO language_mappings VALUES('ad_2','ad','spa','false');
+INSERT INTO language_mappings VALUES('ad_3','ad','por','false');
+INSERT INTO language_mappings VALUES('ao_0','ao','por','true');
+INSERT INTO language_mappings VALUES('ao_1','ao','bnt','false');
+INSERT INTO language_mappings VALUES('ag_0','ag','eng','true');
+INSERT INTO language_mappings VALUES('ar_0','ar','spa','true');
+INSERT INTO language_mappings VALUES('ar_1','ar','eng','false');
+INSERT INTO language_mappings VALUES('ar_2','ar','ita','false');
+INSERT INTO language_mappings VALUES('ar_3','ar','ger','false');
+INSERT INTO language_mappings VALUES('ar_4','ar','fre','false');
+INSERT INTO language_mappings VALUES('am_0','am','hye','true');
+INSERT INTO language_mappings VALUES('au_0','au','eng','true');
+INSERT INTO language_mappings VALUES('at_0','at','ger','true');
+INSERT INTO language_mappings VALUES('at_1','at','slv','false');
+INSERT INTO language_mappings VALUES('at_2','at','hrv','false');
+INSERT INTO language_mappings VALUES('at_3','at','hun','false');
+INSERT INTO language_mappings VALUES('az_0','az','aze','true');
+INSERT INTO language_mappings VALUES('az_1','az','tur','false');
+INSERT INTO language_mappings VALUES('az_2','az','rus','false');
+INSERT INTO language_mappings VALUES('az_3','az','hye','false');
+INSERT INTO language_mappings VALUES('bs_0','bs','eng','true');
+INSERT INTO language_mappings VALUES('bh_0','bh','ara','true');
+INSERT INTO language_mappings VALUES('bh_1','bh','eng','false');
+INSERT INTO language_mappings VALUES('bh_2','bh','per','false');
+INSERT INTO language_mappings VALUES('bh_3','bh','urd','false');
+INSERT INTO language_mappings VALUES('bd_0','bd','ben','true');
+INSERT INTO language_mappings VALUES('bd_1','bd','eng','false');
+INSERT INTO language_mappings VALUES('bb_0','bb','eng','true');
+INSERT INTO language_mappings VALUES('by_0','by','bel','true');
+INSERT INTO language_mappings VALUES('be_0','be','nla','true');
+INSERT INTO language_mappings VALUES('be_1','be','fre','true');
+INSERT INTO language_mappings VALUES('be_2','be','ger','false');
+INSERT INTO language_mappings VALUES('bz_0','bz','eng','true');
+INSERT INTO language_mappings VALUES('bz_1','bz','spa','false');
+INSERT INTO language_mappings VALUES('bj_0','bj','fre','true');
+INSERT INTO language_mappings VALUES('bt_0','bt','dzo','true');
+INSERT INTO language_mappings VALUES('bo_0','bo','spa','true');
+INSERT INTO language_mappings VALUES('bo_1','bo','que','false');
+INSERT INTO language_mappings VALUES('bo_2','bo','aym','false');
+INSERT INTO language_mappings VALUES('ba_0','ba','scr','true');
+INSERT INTO language_mappings VALUES('bw_0','bw','eng','true');
+INSERT INTO language_mappings VALUES('bw_1','bw','tsn','false');
+INSERT INTO language_mappings VALUES('br_0','br','por','true');
+INSERT INTO language_mappings VALUES('bn_0','bn','msa','true');
+INSERT INTO language_mappings VALUES('bn_1','bn','zho','false');
+INSERT INTO language_mappings VALUES('bn_2','bn','eng','false');
+INSERT INTO language_mappings VALUES('bg_0','bg','bul','true');
+INSERT INTO language_mappings VALUES('bf_0','bf','fre','true');
+INSERT INTO language_mappings VALUES('bi_0','bi','run','true');
+INSERT INTO language_mappings VALUES('bi_1','bi','fre','true');
+INSERT INTO language_mappings VALUES('bi_2','bi','swa','false');
+INSERT INTO language_mappings VALUES('kh_0','kh','khm','true');
+INSERT INTO language_mappings VALUES('kh_1','kh','fre','false');
+INSERT INTO language_mappings VALUES('kh_2','kh','eng','false');
+INSERT INTO language_mappings VALUES('cm_0','cm','fre','true');
+INSERT INTO language_mappings VALUES('cm_1','cm','eng','true');
+INSERT INTO language_mappings VALUES('ca_0','ca','eng','true');
+INSERT INTO language_mappings VALUES('ca_1','ca','fre','true');
+INSERT INTO language_mappings VALUES('cv_0','cv','por','true');
+INSERT INTO language_mappings VALUES('cf_0','cf','fre','true');
+INSERT INTO language_mappings VALUES('cf_1','cf','sag','false');
+INSERT INTO language_mappings VALUES('cf_2','cf','ara','false');
+INSERT INTO language_mappings VALUES('cf_3','cf','swa','false');
+INSERT INTO language_mappings VALUES('td_0','td','fre','true');
+INSERT INTO language_mappings VALUES('td_1','td','ara','true');
+INSERT INTO language_mappings VALUES('cl_0','cl','spa','true');
+INSERT INTO language_mappings VALUES('cn_0','cn','zho','true');
+INSERT INTO language_mappings VALUES('co_0','co','spa','true');
+INSERT INTO language_mappings VALUES('km_0','km','fre','true');
+INSERT INTO language_mappings VALUES('km_1','km','ara','true');
+INSERT INTO language_mappings VALUES('cg_0','cg','fre','true');
+INSERT INTO language_mappings VALUES('cg_1','cg','lin','false');
+INSERT INTO language_mappings VALUES('cg_2','cg','kon','false');
+INSERT INTO language_mappings VALUES('cr_0','cr','spa','true');
+INSERT INTO language_mappings VALUES('ci_0','ci','fre','true');
+INSERT INTO language_mappings VALUES('cu_0','cu','spa','true');
+INSERT INTO language_mappings VALUES('cy_0','cy','gre','true');
+INSERT INTO language_mappings VALUES('cy_1','cy','tur','true');
+INSERT INTO language_mappings VALUES('cy_2','cy','eng','false');
+INSERT INTO language_mappings VALUES('cz_0','cz','cze','true');
+INSERT INTO language_mappings VALUES('cz_1','cz','slo','false');
+INSERT INTO language_mappings VALUES('dk_0','dk','dan','true');
+INSERT INTO language_mappings VALUES('dk_1','dk','fao','false');
+INSERT INTO language_mappings VALUES('dk_2','dk','kal','false');
+INSERT INTO language_mappings VALUES('dk_3','dk','ger','false');
+INSERT INTO language_mappings VALUES('dj_0','dj','ara','true');
+INSERT INTO language_mappings VALUES('dj_1','dj','fre','true');
+INSERT INTO language_mappings VALUES('dj_2','dj','aar','false');
+INSERT INTO language_mappings VALUES('dj_3','dj','som','false');
+INSERT INTO language_mappings VALUES('dm_0','dm','eng','true');
+INSERT INTO language_mappings VALUES('dm_1','dm','fre','false');
+INSERT INTO language_mappings VALUES('do_0','do','spa','true');
+INSERT INTO language_mappings VALUES('do_1','do','eng','false');
+INSERT INTO language_mappings VALUES('tl_0','tl','tet','true');
+INSERT INTO language_mappings VALUES('tl_1','tl','por','true');
+INSERT INTO language_mappings VALUES('tl_2','tl','ind','false');
+INSERT INTO language_mappings VALUES('tl_3','tl','eng','false');
+INSERT INTO language_mappings VALUES('ec_0','ec','spa','true');
+INSERT INTO language_mappings VALUES('ec_1','ec','que','false');
+INSERT INTO language_mappings VALUES('eg_0','eg','ara','true');
+INSERT INTO language_mappings VALUES('sv_0','sv','spa','true');
+INSERT INTO language_mappings VALUES('gq_0','gq','spa','true');
+INSERT INTO language_mappings VALUES('gq_1','gq','fre','true');
+INSERT INTO language_mappings VALUES('gq_2','gq','fan','false');
+INSERT INTO language_mappings VALUES('er_0','er','tig','true');
+INSERT INTO language_mappings VALUES('er_1','er','ara','true');
+INSERT INTO language_mappings VALUES('er_2','er','aar','false');
+INSERT INTO language_mappings VALUES('er_3','er','bas','false');
+INSERT INTO language_mappings VALUES('ee_0','ee','est','true');
+INSERT INTO language_mappings VALUES('ee_1','ee','rus','false');
+INSERT INTO language_mappings VALUES('ee_2','ee','fin','false');
+INSERT INTO language_mappings VALUES('ee_3','ee','eng','false');
+INSERT INTO language_mappings VALUES('et_0','et','amh','true');
+INSERT INTO language_mappings VALUES('et_1','et','eng','false');
+INSERT INTO language_mappings VALUES('et_2','et','tir','false');
+INSERT INTO language_mappings VALUES('fj_0','fj','fij','true');
+INSERT INTO language_mappings VALUES('fj_1','fj','hin','false');
+INSERT INTO language_mappings VALUES('fj_2','fj','eng','false');
+INSERT INTO language_mappings VALUES('fi_0','fi','fin','true');
+INSERT INTO language_mappings VALUES('fi_1','fi','sve','true');
+INSERT INTO language_mappings VALUES('fi_2','fi','rus','false');
+INSERT INTO language_mappings VALUES('fr_0','fr','fre','true');
+INSERT INTO language_mappings VALUES('fr_1','fr','bre','false');
+INSERT INTO language_mappings VALUES('fr_2','fr','cos','false');
+INSERT INTO language_mappings VALUES('ga_0','ga','fre','true');
+INSERT INTO language_mappings VALUES('ga_1','ga','fan','false');
+INSERT INTO language_mappings VALUES('ge_0','ge','kat','true');
+INSERT INTO language_mappings VALUES('ge_1','ge','rus','false');
+INSERT INTO language_mappings VALUES('ge_2','ge','hye','false');
+INSERT INTO language_mappings VALUES('ge_3','ge','aze','false');
+INSERT INTO language_mappings VALUES('de_0','de','ger','true');
+INSERT INTO language_mappings VALUES('gh_0','gh','eng','true');
+INSERT INTO language_mappings VALUES('gh_1','gh','twi','false');
+INSERT INTO language_mappings VALUES('gh_2','gh','fat','false');
+INSERT INTO language_mappings VALUES('gh_3','gh','gaa','false');
+INSERT INTO language_mappings VALUES('gh_4','gh','ewe','false');
+INSERT INTO language_mappings VALUES('gr_0','gr','gre','true');
+INSERT INTO language_mappings VALUES('gd_0','gd','eng','true');
+INSERT INTO language_mappings VALUES('gt_0','gt','spa','true');
+INSERT INTO language_mappings VALUES('gn_0','gn','fre','true');
+INSERT INTO language_mappings VALUES('gn_1','gn','sus','false');
+INSERT INTO language_mappings VALUES('gw_0','gw','por','true');
+INSERT INTO language_mappings VALUES('gy_0','gy','eng','true');
+INSERT INTO language_mappings VALUES('ht_0','ht','fre','true');
+INSERT INTO language_mappings VALUES('hn_0','hn','spa','true');
+INSERT INTO language_mappings VALUES('hn_1','hn','eng','false');
+INSERT INTO language_mappings VALUES('hu_0','hu','hun','true');
+INSERT INTO language_mappings VALUES('is_0','is','isl','true');
+INSERT INTO language_mappings VALUES('in_0','in','hin','true');
+INSERT INTO language_mappings VALUES('in_1','in','eng','true');
+INSERT INTO language_mappings VALUES('in_2','in','ben','false');
+INSERT INTO language_mappings VALUES('in_3','in','guj','false');
+INSERT INTO language_mappings VALUES('in_4','in','kas','false');
+INSERT INTO language_mappings VALUES('in_5','in','mal','false');
+INSERT INTO language_mappings VALUES('in_6','in','mar','false');
+INSERT INTO language_mappings VALUES('in_7','in','ori','false');
+INSERT INTO language_mappings VALUES('in_8','in','pan','false');
+INSERT INTO language_mappings VALUES('in_9','in','tam','false');
+INSERT INTO language_mappings VALUES('in_10','in','tel','false');
+INSERT INTO language_mappings VALUES('in_11','in','urd','false');
+INSERT INTO language_mappings VALUES('in_12','in','kan','false');
+INSERT INTO language_mappings VALUES('in_13','in','asm','false');
+INSERT INTO language_mappings VALUES('in_14','in','san','false');
+INSERT INTO language_mappings VALUES('in_15','in','snd','false');
+INSERT INTO language_mappings VALUES('id_0','id','ind','true');
+INSERT INTO language_mappings VALUES('id_1','id','nla','false');
+INSERT INTO language_mappings VALUES('id_2','id','eng','false');
+INSERT INTO language_mappings VALUES('ir_0','ir','per','true');
+INSERT INTO language_mappings VALUES('ir_1','ir','kur','false');
+INSERT INTO language_mappings VALUES('ir_2','ir','ara','false');
+INSERT INTO language_mappings VALUES('iq_0','iq','ara','true');
+INSERT INTO language_mappings VALUES('iq_1','iq','kur','false');
+INSERT INTO language_mappings VALUES('ie_0','ie','eng','true');
+INSERT INTO language_mappings VALUES('ie_1','ie','iri','false');
+INSERT INTO language_mappings VALUES('ie_2','ie','gae','false');
+INSERT INTO language_mappings VALUES('il_0','il','heb','true');
+INSERT INTO language_mappings VALUES('il_1','il','ara','false');
+INSERT INTO language_mappings VALUES('il_2','il','eng','false');
+INSERT INTO language_mappings VALUES('it_0','it','ita','true');
+INSERT INTO language_mappings VALUES('it_1','it','ger','false');
+INSERT INTO language_mappings VALUES('it_2','it','fre','false');
+INSERT INTO language_mappings VALUES('it_3','it','slv','false');
+INSERT INTO language_mappings VALUES('jm_0','jm','eng','true');
+INSERT INTO language_mappings VALUES('jp_0','jp','jpn','true');
+INSERT INTO language_mappings VALUES('jo_0','jo','ara','true');
+INSERT INTO language_mappings VALUES('jo_1','jo','eng','false');
+INSERT INTO language_mappings VALUES('kz_0','kz','kaz','true');
+INSERT INTO language_mappings VALUES('kz_1','kz','rus','true');
+INSERT INTO language_mappings VALUES('ke_0','ke','eng','true');
+INSERT INTO language_mappings VALUES('ke_1','ke','swa','false');
+INSERT INTO language_mappings VALUES('ki_0','ki','eng','true');
+INSERT INTO language_mappings VALUES('ki_1','ki','gil','false');
+INSERT INTO language_mappings VALUES('kp_0','kp','kor','true');
+INSERT INTO language_mappings VALUES('kr_0','kr','kor','true');
+INSERT INTO language_mappings VALUES('kw_0','kw','ara','true');
+INSERT INTO language_mappings VALUES('kw_1','kw','eng','false');
+INSERT INTO language_mappings VALUES('kg_0','kg','kir','true');
+INSERT INTO language_mappings VALUES('kg_1','kg','rus','false');
+INSERT INTO language_mappings VALUES('la_0','la','lao','true');
+INSERT INTO language_mappings VALUES('la_1','la','fre','false');
+INSERT INTO language_mappings VALUES('la_2','la','eng','false');
+INSERT INTO language_mappings VALUES('lv_0','lv','lav','true');
+INSERT INTO language_mappings VALUES('lb_0','lb','ara','true');
+INSERT INTO language_mappings VALUES('lb_1','lb','fre','false');
+INSERT INTO language_mappings VALUES('lb_2','lb','eng','false');
+INSERT INTO language_mappings VALUES('ls_0','ls','eng','true');
+INSERT INTO language_mappings VALUES('ls_1','ls','zul','false');
+INSERT INTO language_mappings VALUES('ls_2','ls','xho','false');
+INSERT INTO language_mappings VALUES('lr_0','lr','eng','true');
+INSERT INTO language_mappings VALUES('ly_0','ly','ara','true');
+INSERT INTO language_mappings VALUES('ly_1','ly','ita','false');
+INSERT INTO language_mappings VALUES('ly_2','ly','eng','false');
+INSERT INTO language_mappings VALUES('li_0','li','ger','true');
+INSERT INTO language_mappings VALUES('lt_0','lt','lit','true');
+INSERT INTO language_mappings VALUES('lt_1','lt','pol','false');
+INSERT INTO language_mappings VALUES('lt_2','lt','rus','false');
+INSERT INTO language_mappings VALUES('lu_0','lu','fre','true');
+INSERT INTO language_mappings VALUES('lu_1','lu','ger','true');
+INSERT INTO language_mappings VALUES('mk_0','mk','mak','true');
+INSERT INTO language_mappings VALUES('mk_1','mk','sqi','true');
+INSERT INTO language_mappings VALUES('mk_2','mk','tur','false');
+INSERT INTO language_mappings VALUES('mg_0','mg','mlg','true');
+INSERT INTO language_mappings VALUES('mg_1','mg','fre','true');
+INSERT INTO language_mappings VALUES('mw_0','mw','eng','true');
+INSERT INTO language_mappings VALUES('my_0','my','msa','true');
+INSERT INTO language_mappings VALUES('my_1','my','zho','false');
+INSERT INTO language_mappings VALUES('my_2','my','tam','false');
+INSERT INTO language_mappings VALUES('my_3','my','eng','false');
+INSERT INTO language_mappings VALUES('mv_0','mv','div','true');
+INSERT INTO language_mappings VALUES('mv_1','mv','ara','false');
+INSERT INTO language_mappings VALUES('mv_2','mv','hin','false');
+INSERT INTO language_mappings VALUES('mv_3','mv','eng','false');
+INSERT INTO language_mappings VALUES('ml_0','ml','fre','true');
+INSERT INTO language_mappings VALUES('mt_0','mt','mlt','true');
+INSERT INTO language_mappings VALUES('mt_1','mt','eng','true');
+INSERT INTO language_mappings VALUES('mh_0','mh','mah','true');
+INSERT INTO language_mappings VALUES('mh_1','mh','eng','true');
+INSERT INTO language_mappings VALUES('mr_0','mr','ara','true');
+INSERT INTO language_mappings VALUES('mr_1','mr','wol','true');
+INSERT INTO language_mappings VALUES('mr_2','mr','fre','false');
+INSERT INTO language_mappings VALUES('mu_0','mu','eng','true');
+INSERT INTO language_mappings VALUES('mu_1','mu','fre','true');
+INSERT INTO language_mappings VALUES('mu_2','mu','hin','false');
+INSERT INTO language_mappings VALUES('mu_3','mu','urd','false');
+INSERT INTO language_mappings VALUES('mu_4','mu','bho','false');
+INSERT INTO language_mappings VALUES('mx_0','mx','spa','true');
+INSERT INTO language_mappings VALUES('mc_0','mc','fre','true');
+INSERT INTO language_mappings VALUES('mc_1','mc','eng','false');
+INSERT INTO language_mappings VALUES('mc_2','mc','ita','false');
+INSERT INTO language_mappings VALUES('mn_0','mn','mon','true');
+INSERT INTO language_mappings VALUES('mn_1','mn','rus','false');
+INSERT INTO language_mappings VALUES('mn_2','mn','zho','false');
+INSERT INTO language_mappings VALUES('ma_0','ma','ara','true');
+INSERT INTO language_mappings VALUES('ma_1','ma','fre','false');
+INSERT INTO language_mappings VALUES('ma_2','ma','spa','false');
+INSERT INTO language_mappings VALUES('mz_0','mz','por','true');
+INSERT INTO language_mappings VALUES('mz_1','mz','bnt','false');
+INSERT INTO language_mappings VALUES('mm_0','mm','mya','true');
+INSERT INTO language_mappings VALUES('na_0','na','afr','true');
+INSERT INTO language_mappings VALUES('na_1','na','ger','true');
+INSERT INTO language_mappings VALUES('na_2','na','eng','true');
+INSERT INTO language_mappings VALUES('nr_0','nr','nau','true');
+INSERT INTO language_mappings VALUES('nr_1','nr','eng','false');
+INSERT INTO language_mappings VALUES('np_0','np','nep','true');
+INSERT INTO language_mappings VALUES('np_1','np','new','false');
+INSERT INTO language_mappings VALUES('np_2','np','mai','false');
+INSERT INTO language_mappings VALUES('nl_0','nl','nla','true');
+INSERT INTO language_mappings VALUES('nl_1','nl','fry','false');
+INSERT INTO language_mappings VALUES('nz_0','nz','eng','true');
+INSERT INTO language_mappings VALUES('nz_1','nz','mri','false');
+INSERT INTO language_mappings VALUES('ni_0','ni','spa','true');
+INSERT INTO language_mappings VALUES('ne_0','ne','fre','true');
+INSERT INTO language_mappings VALUES('ne_1','ne','hau','false');
+INSERT INTO language_mappings VALUES('ne_2','ne','son','false');
+INSERT INTO language_mappings VALUES('ne_3','ne','ara','false');
+INSERT INTO language_mappings VALUES('ng_0','ng','eng','true');
+INSERT INTO language_mappings VALUES('ng_1','ng','hau','false');
+INSERT INTO language_mappings VALUES('ng_2','ng','yor','false');
+INSERT INTO language_mappings VALUES('ng_3','ng','ibo','false');
+INSERT INTO language_mappings VALUES('no_0','no','nno','true');
+INSERT INTO language_mappings VALUES('om_0','om','ara','true');
+INSERT INTO language_mappings VALUES('om_1','om','eng','false');
+INSERT INTO language_mappings VALUES('pk_0','pk','urd','true');
+INSERT INTO language_mappings VALUES('pk_1','pk','eng','true');
+INSERT INTO language_mappings VALUES('pk_2','pk','pan','false');
+INSERT INTO language_mappings VALUES('pk_3','pk','snd','false');
+INSERT INTO language_mappings VALUES('pk_4','pk','pus','false');
+INSERT INTO language_mappings VALUES('pk_5','pk','bal','false');
+INSERT INTO language_mappings VALUES('pw_0','pw','pau','true');
+INSERT INTO language_mappings VALUES('pw_1','pw','eng','true');
+INSERT INTO language_mappings VALUES('pa_0','pa','spa','true');
+INSERT INTO language_mappings VALUES('pa_1','pa','eng','false');
+INSERT INTO language_mappings VALUES('pg_0','pg','eng','true');
+INSERT INTO language_mappings VALUES('pg_1','pg','hmo','false');
+INSERT INTO language_mappings VALUES('py_0','py','spa','true');
+INSERT INTO language_mappings VALUES('py_1','py','grn','false');
+INSERT INTO language_mappings VALUES('pe_0','pe','spa','true');
+INSERT INTO language_mappings VALUES('pe_1','pe','que','true');
+INSERT INTO language_mappings VALUES('pe_2','pe','aym','false');
+INSERT INTO language_mappings VALUES('ph_0','ph','tgl','true');
+INSERT INTO language_mappings VALUES('ph_1','ph','eng','true');
+INSERT INTO language_mappings VALUES('ph_2','ph','ilo','false');
+INSERT INTO language_mappings VALUES('ph_3','ph','ceb','false');
+INSERT INTO language_mappings VALUES('pl_0','pl','pol','true');
+INSERT INTO language_mappings VALUES('pt_0','pt','por','true');
+INSERT INTO language_mappings VALUES('qa_0','qa','ara','true');
+INSERT INTO language_mappings VALUES('qa_1','qa','eng','false');
+INSERT INTO language_mappings VALUES('ro_0','ro','rum','true');
+INSERT INTO language_mappings VALUES('ro_1','ro','hun','false');
+INSERT INTO language_mappings VALUES('ro_2','ro','ger','false');
+INSERT INTO language_mappings VALUES('ru_0','ru','rus','true');
+INSERT INTO language_mappings VALUES('rw_0','rw','kin','true');
+INSERT INTO language_mappings VALUES('rw_1','rw','fre','true');
+INSERT INTO language_mappings VALUES('rw_2','rw','eng','true');
+INSERT INTO language_mappings VALUES('kn_0','kn','eng','true');
+INSERT INTO language_mappings VALUES('lc_0','lc','eng','true');
+INSERT INTO language_mappings VALUES('vc_0','vc','eng','true');
+INSERT INTO language_mappings VALUES('vc_1','vc','fre','false');
+INSERT INTO language_mappings VALUES('ws_0','ws','smo','true');
+INSERT INTO language_mappings VALUES('ws_1','ws','eng','true');
+INSERT INTO language_mappings VALUES('sm_0','sm','ita','true');
+INSERT INTO language_mappings VALUES('st_0','st','por','true');
+INSERT INTO language_mappings VALUES('sa_0','sa','ara','true');
+INSERT INTO language_mappings VALUES('sa_1','sa','eng','false');
+INSERT INTO language_mappings VALUES('sn_0','sn','fre','true');
+INSERT INTO language_mappings VALUES('sn_1','sn','wol','false');
+INSERT INTO language_mappings VALUES('sn_2','sn','srr','false');
+INSERT INTO language_mappings VALUES('sc_0','sc','eng','true');
+INSERT INTO language_mappings VALUES('sc_1','sc','fre','true');
+INSERT INTO language_mappings VALUES('sl_0','sl','eng','true');
+INSERT INTO language_mappings VALUES('sl_1','sl','men','false');
+INSERT INTO language_mappings VALUES('sg_0','sg','msa','true');
+INSERT INTO language_mappings VALUES('sg_1','sg','zho','true');
+INSERT INTO language_mappings VALUES('sg_2','sg','tam','true');
+INSERT INTO language_mappings VALUES('sg_3','sg','eng','true');
+INSERT INTO language_mappings VALUES('sk_0','sk','slo','true');
+INSERT INTO language_mappings VALUES('sk_1','sk','hun','false');
+INSERT INTO language_mappings VALUES('si_0','si','slv','true');
+INSERT INTO language_mappings VALUES('si_1','si','scr','false');
+INSERT INTO language_mappings VALUES('sb_0','sb','eng','true');
+INSERT INTO language_mappings VALUES('so_0','so','som','true');
+INSERT INTO language_mappings VALUES('so_1','so','ara','false');
+INSERT INTO language_mappings VALUES('so_2','so','eng','false');
+INSERT INTO language_mappings VALUES('so_3','so','ita','false');
+INSERT INTO language_mappings VALUES('za_0','za','xho','true');
+INSERT INTO language_mappings VALUES('za_1','za','zul','true');
+INSERT INTO language_mappings VALUES('za_2','za','eng','true');
+INSERT INTO language_mappings VALUES('za_3','za','afr','true');
+INSERT INTO language_mappings VALUES('za_4','za','ssw','true');
+INSERT INTO language_mappings VALUES('za_5','za','tso','true');
+INSERT INTO language_mappings VALUES('za_6','za','ven','true');
+INSERT INTO language_mappings VALUES('za_7','za','tsn','true');
+INSERT INTO language_mappings VALUES('za_8','za','ven','false');
+INSERT INTO language_mappings VALUES('es_0','es','spa','true');
+INSERT INTO language_mappings VALUES('es_1','es','cat','false');
+INSERT INTO language_mappings VALUES('es_2','es','eus','false');
+INSERT INTO language_mappings VALUES('lk_0','lk','sin','true');
+INSERT INTO language_mappings VALUES('lk_1','lk','tam','false');
+INSERT INTO language_mappings VALUES('lk_2','lk','eng','false');
+INSERT INTO language_mappings VALUES('sd_0','sd','ara','true');
+INSERT INTO language_mappings VALUES('sd_1','sd','eng','false');
+INSERT INTO language_mappings VALUES('sr_0','sr','nla','true');
+INSERT INTO language_mappings VALUES('sr_1','sr','eng','false');
+INSERT INTO language_mappings VALUES('sz_0','sz','eng','true');
+INSERT INTO language_mappings VALUES('sz_1','sz','ssw','true');
+INSERT INTO language_mappings VALUES('se_0','se','sve','true');
+INSERT INTO language_mappings VALUES('ch_0','ch','ger','true');
+INSERT INTO language_mappings VALUES('ch_1','ch','fre','true');
+INSERT INTO language_mappings VALUES('ch_2','ch','ita','true');
+INSERT INTO language_mappings VALUES('ch_3','ch','roh','false');
+INSERT INTO language_mappings VALUES('sy_0','sy','ara','true');
+INSERT INTO language_mappings VALUES('sy_1','sy','fre','false');
+INSERT INTO language_mappings VALUES('sy_2','sy','eng','false');
+INSERT INTO language_mappings VALUES('tw_0','tw','zho','true');
+INSERT INTO language_mappings VALUES('tj_0','tj','tgk','true');
+INSERT INTO language_mappings VALUES('tz_0','tz','swa','true');
+INSERT INTO language_mappings VALUES('tz_1','tz','eng','true');
+INSERT INTO language_mappings VALUES('th_0','th','tha','true');
+INSERT INTO language_mappings VALUES('th_1','th','zho','false');
+INSERT INTO language_mappings VALUES('th_2','th','eng','false');
+INSERT INTO language_mappings VALUES('tg_0','tg','fre','true');
+INSERT INTO language_mappings VALUES('tg_1','tg','ewe','false');
+INSERT INTO language_mappings VALUES('tg_2','tg','kab','false');
+INSERT INTO language_mappings VALUES('to_0','to','ton','true');
+INSERT INTO language_mappings VALUES('to_1','to','eng','false');
+INSERT INTO language_mappings VALUES('tt_0','tt','eng','true');
+INSERT INTO language_mappings VALUES('tt_1','tt','hin','false');
+INSERT INTO language_mappings VALUES('tt_2','tt','fre','false');
+INSERT INTO language_mappings VALUES('tt_3','tt','spa','false');
+INSERT INTO language_mappings VALUES('tn_0','tn','ara','true');
+INSERT INTO language_mappings VALUES('tn_1','tn','fre','false');
+INSERT INTO language_mappings VALUES('tr_0','tr','tur','true');
+INSERT INTO language_mappings VALUES('tm_0','tm','tuk','true');
+INSERT INTO language_mappings VALUES('tm_1','tm','rus','false');
+INSERT INTO language_mappings VALUES('tm_2','tm','uzb','false');
+INSERT INTO language_mappings VALUES('tv_0','tv','tvl','true');
+INSERT INTO language_mappings VALUES('tv_1','tv','eng','true');
+INSERT INTO language_mappings VALUES('tv_2','tv','smo','true');
+INSERT INTO language_mappings VALUES('ug_0','ug','eng','true');
+INSERT INTO language_mappings VALUES('ug_1','ug','swa','false');
+INSERT INTO language_mappings VALUES('ua_0','ua','ukr','true');
+INSERT INTO language_mappings VALUES('ae_0','ae','ara','true');
+INSERT INTO language_mappings VALUES('ae_1','ae','eng','false');
+INSERT INTO language_mappings VALUES('gb_0','gb','eng','true');
+INSERT INTO language_mappings VALUES('gb_1','gb','wel','false');
+INSERT INTO language_mappings VALUES('gb_2','gb','gae','false');
+INSERT INTO language_mappings VALUES('us_0','us','eng','true');
+INSERT INTO language_mappings VALUES('us_1','us','spa','false');
+INSERT INTO language_mappings VALUES('uy_0','uy','spa','true');
+INSERT INTO language_mappings VALUES('uz_0','uz','uzb','true');
+INSERT INTO language_mappings VALUES('uz_1','uz','rus','false');
+INSERT INTO language_mappings VALUES('uz_2','uz','tgk','false');
+INSERT INTO language_mappings VALUES('vu_0','vu','bis','true');
+INSERT INTO language_mappings VALUES('vu_1','vu','eng','true');
+INSERT INTO language_mappings VALUES('vu_2','vu','fre','true');
+INSERT INTO language_mappings VALUES('va_0','va','ita','true');
+INSERT INTO language_mappings VALUES('va_1','va','lat','false');
+INSERT INTO language_mappings VALUES('ve_0','ve','spa','true');
+INSERT INTO language_mappings VALUES('vn_0','vn','vie','true');
+INSERT INTO language_mappings VALUES('vn_1','vn','fre','false');
+INSERT INTO language_mappings VALUES('vn_2','vn','eng','false');
+INSERT INTO language_mappings VALUES('vn_3','vn','khm','false');
+INSERT INTO language_mappings VALUES('vn_4','vn','zho','false');
+INSERT INTO language_mappings VALUES('eh_0','eh','ara','true');
+INSERT INTO language_mappings VALUES('ye_0','ye','ara','true');
+INSERT INTO language_mappings VALUES('zm_0','zm','eng','true');
+INSERT INTO language_mappings VALUES('zw_0','zw','eng','true');
+INSERT INTO language_mappings VALUES('zw_1','zw','sna','false');
+INSERT INTO language_mappings VALUES('cd_0','cd','fre','true');
+INSERT INTO language_mappings VALUES('cd_1','cd','lin','false');
+INSERT INTO language_mappings VALUES('cd_2','cd','swa','false');
+CREATE TABLE timezone (
+ country_code char(2),
+ timezone char(50),
+ is_default boolean
+);
+INSERT INTO timezone VALUES('ag','America/Antigua','true');
+INSERT INTO timezone VALUES('ai','America/Anguilla','true');
+INSERT INTO timezone VALUES('an','America/Curacao','true');
+INSERT INTO timezone VALUES('ar','America/Buenos_Aires','true');
+INSERT INTO timezone VALUES('ar','America/Catamarca','false');
+INSERT INTO timezone VALUES('ar','America/Cordoba','false');
+INSERT INTO timezone VALUES('ar','America/Cordoba','false');
+INSERT INTO timezone VALUES('ar','America/Jujuy','false');
+INSERT INTO timezone VALUES('ar','America/Mendoza','false');
+INSERT INTO timezone VALUES('aw','America/Aruba','true');
+INSERT INTO timezone VALUES('bb','America/Barbados','true');
+INSERT INTO timezone VALUES('bo','America/La_Paz','true');
+INSERT INTO timezone VALUES('br','America/Rio_Branco','false');
+INSERT INTO timezone VALUES('br','America/Eirunepe','false');
+INSERT INTO timezone VALUES('br','America/Manaus','false');
+INSERT INTO timezone VALUES('br','America/Boa_Vista','false');
+INSERT INTO timezone VALUES('br','America/Porto_Velho','false');
+INSERT INTO timezone VALUES('br','America/Cuiaba','false');
+INSERT INTO timezone VALUES('br','America/Sao_Paulo','false');
+INSERT INTO timezone VALUES('br','America/Maceio','false');
+INSERT INTO timezone VALUES('br','America/Araguaina','false');
+INSERT INTO timezone VALUES('br','America/Recife','false');
+INSERT INTO timezone VALUES('br','America/Fortaleza','false');
+INSERT INTO timezone VALUES('br','America/Belem','false');
+INSERT INTO timezone VALUES('br','America/Noronha','true');
+INSERT INTO timezone VALUES('bs','America/Nassau','true');
+INSERT INTO timezone VALUES('bz','America/Belize','true');
+INSERT INTO timezone VALUES('ca','America/Dawson','false');
+INSERT INTO timezone VALUES('ca','America/Vancouver','false');
+INSERT INTO timezone VALUES('ca','America/Whitehorse','false');
+INSERT INTO timezone VALUES('ca','America/Dawson_Creek','false');
+INSERT INTO timezone VALUES('ca','America/Inuvik','false');
+INSERT INTO timezone VALUES('ca','America/Yellowknife','false');
+INSERT INTO timezone VALUES('ca','America/Edmonton','false');
+INSERT INTO timezone VALUES('ca','America/Cambridge_Bay','false');
+INSERT INTO timezone VALUES('ca','America/Winnipeg','false');
+INSERT INTO timezone VALUES('ca','America/Rainy_River','false');
+INSERT INTO timezone VALUES('ca','America/Regina','false');
+INSERT INTO timezone VALUES('ca','America/Swift_Current','false');
+INSERT INTO timezone VALUES('ca','America/Rankin_Inlet','false');
+INSERT INTO timezone VALUES('ca','America/Iqaluit','false');
+INSERT INTO timezone VALUES('ca','America/Montreal','true');
+INSERT INTO timezone VALUES('ca','America/Thunder_Bay','false');
+INSERT INTO timezone VALUES('ca','America/Nipigon','false');
+INSERT INTO timezone VALUES('ca','America/Pangnirtung','false');
+INSERT INTO timezone VALUES('ca','America/Glace_Bay','false');
+INSERT INTO timezone VALUES('ca','America/Goose_Bay','false');
+INSERT INTO timezone VALUES('ca','America/Halifax','false');
+INSERT INTO timezone VALUES('ca','America/St_Johns','false');
+INSERT INTO timezone VALUES('cl','America/Santiago','true');
+INSERT INTO timezone VALUES('co','America/Bogota','true');
+INSERT INTO timezone VALUES('cr','America/Costa_Rica','true');
+INSERT INTO timezone VALUES('cu','America/Havana','true');
+INSERT INTO timezone VALUES('dm','America/Dominica','true');
+INSERT INTO timezone VALUES('do','America/Santo_Domingo','true');
+INSERT INTO timezone VALUES('ec','America/Guayaquil','true');
+INSERT INTO timezone VALUES('gd','America/Grenada','true');
+INSERT INTO timezone VALUES('gf','America/Cayenne','true');
+INSERT INTO timezone VALUES('gl','America/Danmarkshavn','false');
+INSERT INTO timezone VALUES('gl','America/Scoresbysund','false');
+INSERT INTO timezone VALUES('gl','America/Thule','false');
+INSERT INTO timezone VALUES('gp','America/Guadeloupe','true');
+INSERT INTO timezone VALUES('gt','America/Guatemala','true');
+INSERT INTO timezone VALUES('gy','America/Guyana','true');
+INSERT INTO timezone VALUES('hn','America/Tegucigalpa','true');
+INSERT INTO timezone VALUES('ht','America/Port-au-Prince','true');
+INSERT INTO timezone VALUES('jm','America/Jamaica','true');
+INSERT INTO timezone VALUES('kn','America/St_Kitts','true');
+INSERT INTO timezone VALUES('ky','America/Cayman','true');
+INSERT INTO timezone VALUES('lc','America/St_Lucia','true');
+INSERT INTO timezone VALUES('mq','America/Martinique','true');
+INSERT INTO timezone VALUES('ms','America/Montserrat','true');
+INSERT INTO timezone VALUES('mx','America/Tijuana','false');
+INSERT INTO timezone VALUES('mx','America/Chihuahua','false');
+INSERT INTO timezone VALUES('mx','America/Hermosillo','false');
+INSERT INTO timezone VALUES('mx','America/Mazatlan','false');
+INSERT INTO timezone VALUES('mx','America/Merida','false');
+INSERT INTO timezone VALUES('mx','America/Mexico_City','true');
+INSERT INTO timezone VALUES('mx','America/Monterrey','false');
+INSERT INTO timezone VALUES('mx','America/Cancun','false');
+INSERT INTO timezone VALUES('ni','America/Managua','true');
+INSERT INTO timezone VALUES('pa','America/Panama','true');
+INSERT INTO timezone VALUES('pe','America/Lima','true');
+INSERT INTO timezone VALUES('pm','America/Miquelon','true');
+INSERT INTO timezone VALUES('pr','America/Puerto_Rico','true');
+INSERT INTO timezone VALUES('py','America/Asuncion','true');
+INSERT INTO timezone VALUES('sr','America/Paramaribo','true');
+INSERT INTO timezone VALUES('sv','America/El_Salvador','true');
+INSERT INTO timezone VALUES('tc','America/Grand_Turk','true');
+INSERT INTO timezone VALUES('tt','America/Port_of_Spain','true');
+INSERT INTO timezone VALUES('us','America/Adak','false');
+INSERT INTO timezone VALUES('us','America/Anchorage','false');
+INSERT INTO timezone VALUES('us','America/Boise','false');
+INSERT INTO timezone VALUES('us','America/Chicago','false');
+INSERT INTO timezone VALUES('us','America/Denver','false');
+INSERT INTO timezone VALUES('us','America/Detroit','false');
+INSERT INTO timezone VALUES('us','America/Indiana/Knox','false');
+INSERT INTO timezone VALUES('us','America/Indiana/Marengo','false');
+INSERT INTO timezone VALUES('us','America/Indiana/Vevay','false');
+INSERT INTO timezone VALUES('us','America/Indianapolis','false');
+INSERT INTO timezone VALUES('us','America/Juneau','false');
+INSERT INTO timezone VALUES('us','America/Kentucky/Monticello','false');
+INSERT INTO timezone VALUES('us','America/Los_Angeles','false');
+INSERT INTO timezone VALUES('us','America/Louisville','false');
+INSERT INTO timezone VALUES('us','America/Menominee','false');
+INSERT INTO timezone VALUES('us','America/New_York','true');
+INSERT INTO timezone VALUES('us','America/Nome','false');
+INSERT INTO timezone VALUES('us','America/North_Dakota/Center','false');
+INSERT INTO timezone VALUES('us','America/Phoenix','false');
+INSERT INTO timezone VALUES('us','America/Shiprock','false');
+INSERT INTO timezone VALUES('us','America/Yakutat','false');
+INSERT INTO timezone VALUES('uy','America/Montevideo','true');
+INSERT INTO timezone VALUES('vc','America/St_Vincent','true');
+INSERT INTO timezone VALUES('ve','America/Caracas','true');
+INSERT INTO timezone VALUES('vg','America/Tortola','true');
+INSERT INTO timezone VALUES('vi','America/St_Thomas','true');
+INSERT INTO timezone VALUES('ae','Asia/Dubai','true');
+INSERT INTO timezone VALUES('af','Asia/Kabul','true');
+INSERT INTO timezone VALUES('am','Asia/Yerevan','true');
+INSERT INTO timezone VALUES('az','Asia/Baku','true');
+INSERT INTO timezone VALUES('bd','Asia/Dhaka','true');
+INSERT INTO timezone VALUES('bh','Asia/Bahrain','true');
+INSERT INTO timezone VALUES('bn','Asia/Brunei','true');
+INSERT INTO timezone VALUES('bt','Asia/Thimphu','true');
+INSERT INTO timezone VALUES('cn','Asia/Chongqing','false');
+INSERT INTO timezone VALUES('cn','Asia/Harbin','false');
+INSERT INTO timezone VALUES('cn','Asia/Kashgar','false');
+INSERT INTO timezone VALUES('cn','Asia/Shanghai','true');
+INSERT INTO timezone VALUES('cn','Asia/Urumqi','false');
+INSERT INTO timezone VALUES('cy','Asia/Nicosia','true');
+INSERT INTO timezone VALUES('ge','Asia/Tbilisi','true');
+INSERT INTO timezone VALUES('hk','Asia/Hong_Kong','true');
+INSERT INTO timezone VALUES('id','Asia/Jakarta','true');
+INSERT INTO timezone VALUES('id','Asia/Jayapura','false');
+INSERT INTO timezone VALUES('id','Asia/Makassar','false');
+INSERT INTO timezone VALUES('id','Asia/Pontianak','false');
+INSERT INTO timezone VALUES('il','Asia/Jerusalem','true');
+INSERT INTO timezone VALUES('in','Asia/Calcutta','true');
+INSERT INTO timezone VALUES('iq','Asia/Baghdad','true');
+INSERT INTO timezone VALUES('ir','Asia/Tehran','true');
+INSERT INTO timezone VALUES('jo','Asia/Amman','true');
+INSERT INTO timezone VALUES('jp','Asia/Tokyo','true');
+INSERT INTO timezone VALUES('kg','Asia/Bishkek','true');
+INSERT INTO timezone VALUES('kh','Asia/Phnom_Penh','true');
+INSERT INTO timezone VALUES('kp','Asia/Pyongyang','true');
+INSERT INTO timezone VALUES('kr','Asia/Seoul','true');
+INSERT INTO timezone VALUES('kw','Asia/Kuwait','true');
+INSERT INTO timezone VALUES('kz','Asia/Almaty','true');
+INSERT INTO timezone VALUES('kz','Asia/Aqtau','false');
+INSERT INTO timezone VALUES('kz','Asia/Aqtobe','false');
+INSERT INTO timezone VALUES('kz','Asia/Oral','false');
+INSERT INTO timezone VALUES('kz','Asia/Qyzylorda','false');
+INSERT INTO timezone VALUES('la','Asia/Vientiane','true');
+INSERT INTO timezone VALUES('lb','Asia/Beirut','true');
+INSERT INTO timezone VALUES('lk','Asia/Colombo','true');
+INSERT INTO timezone VALUES('mm','Asia/Rangoon','true');
+INSERT INTO timezone VALUES('mn','Asia/Choibalsan','false');
+INSERT INTO timezone VALUES('mn','Asia/Hovd','false');
+INSERT INTO timezone VALUES('mo','Asia/Macau','true');
+INSERT INTO timezone VALUES('my','Asia/Kuala_Lumpur','true');
+INSERT INTO timezone VALUES('my','Asia/Kuching','false');
+INSERT INTO timezone VALUES('np','Asia/Katmandu','true');
+INSERT INTO timezone VALUES('om','Asia/Muscat','true');
+INSERT INTO timezone VALUES('ph','Asia/Manila','true');
+INSERT INTO timezone VALUES('pk','Asia/Karachi','true');
+INSERT INTO timezone VALUES('ps','Asia/Gaza','true');
+INSERT INTO timezone VALUES('qa','Asia/Qatar','true');
+INSERT INTO timezone VALUES('ru','Asia/Anadyr','false');
+INSERT INTO timezone VALUES('ru','Asia/Irkutsk','false');
+INSERT INTO timezone VALUES('ru','Asia/Kamchatka','false');
+INSERT INTO timezone VALUES('ru','Asia/Krasnoyarsk','false');
+INSERT INTO timezone VALUES('ru','Asia/Magadan','false');
+INSERT INTO timezone VALUES('ru','Asia/Novosibirsk','false');
+INSERT INTO timezone VALUES('ru','Asia/Omsk','false');
+INSERT INTO timezone VALUES('ru','Asia/Sakhalin','false');
+INSERT INTO timezone VALUES('ru','Asia/Vladivostok','false');
+INSERT INTO timezone VALUES('ru','Asia/Yakutsk','false');
+INSERT INTO timezone VALUES('ru','Asia/Yekaterinburg','false');
+INSERT INTO timezone VALUES('ru','Europe/Kaliningrad','false');
+INSERT INTO timezone VALUES('ru','Europe/Moscow','false');
+INSERT INTO timezone VALUES('ru','Europe/Samara','false');
+INSERT INTO timezone VALUES('sa','Asia/Riyadh','true');
+INSERT INTO timezone VALUES('sg','Asia/Singapore','true');
+INSERT INTO timezone VALUES('sy','Asia/Damascus','true');
+INSERT INTO timezone VALUES('th','Asia/Bangkok','true');
+INSERT INTO timezone VALUES('tj','Asia/Dushanbe','true');
+INSERT INTO timezone VALUES('tl','Asia/Dili','true');
+INSERT INTO timezone VALUES('tm','Asia/Ashgabat','true');
+INSERT INTO timezone VALUES('tw','Asia/Taipei','true');
+INSERT INTO timezone VALUES('uz','Asia/Samarkand','true');
+INSERT INTO timezone VALUES('uz','Asia/Tashkent','false');
+INSERT INTO timezone VALUES('vn','Asia/Saigon','true');
+INSERT INTO timezone VALUES('ye','Asia/Aden','true');
+INSERT INTO timezone VALUES('bm','Atlantic/Bermuda','true');
+INSERT INTO timezone VALUES('cv','Atlantic/Cape_Verde','true');
+INSERT INTO timezone VALUES('es','Atlantic/Canary','true');
+INSERT INTO timezone VALUES('fk','Atlantic/Stanley','true');
+INSERT INTO timezone VALUES('fo','Atlantic/Faeroe','true');
+INSERT INTO timezone VALUES('gs','Atlantic/South_Georgia','true');
+INSERT INTO timezone VALUES('is','Atlantic/Reykjavik','true');
+INSERT INTO timezone VALUES('sh','Atlantic/St_Helena','true');
+INSERT INTO timezone VALUES('sj','Atlantic/Jan_Mayen','true');
+INSERT INTO timezone VALUES('pt','Atlantic/Madeira','false');
+INSERT INTO timezone VALUES('pt','Atlantic/Azores','false');
+INSERT INTO timezone VALUES('as','Pacific/Pago_Pago','true');
+INSERT INTO timezone VALUES('ck','Pacific/Rarotonga','true');
+INSERT INTO timezone VALUES('cl','Pacific/Easter','true');
+INSERT INTO timezone VALUES('ec','Pacific/Galapagos','true');
+INSERT INTO timezone VALUES('fj','Pacific/Fiji','true');
+INSERT INTO timezone VALUES('fm','Pacific/Yap','true');
+INSERT INTO timezone VALUES('gu','Pacific/Guam','true');
+INSERT INTO timezone VALUES('ki','Pacific/Tarawa','true');
+INSERT INTO timezone VALUES('mh','Pacific/Majuro','true');
+INSERT INTO timezone VALUES('mp','Pacific/Saipan','true');
+INSERT INTO timezone VALUES('nc','Pacific/Noumea','true');
+INSERT INTO timezone VALUES('nf','Pacific/Norfolk','true');
+INSERT INTO timezone VALUES('nr','Pacific/Nauru','true');
+INSERT INTO timezone VALUES('nu','Pacific/Niue','true');
+INSERT INTO timezone VALUES('nz','Pacific/Auckland','true');
+INSERT INTO timezone VALUES('pf','Pacific/Tahiti','true');
+INSERT INTO timezone VALUES('pg','Pacific/Port_Moresby','true');
+INSERT INTO timezone VALUES('pn','Pacific/Pitcairn','true');
+INSERT INTO timezone VALUES('pw','Pacific/Palau','true');
+INSERT INTO timezone VALUES('sb','Pacific/Guadalcanal','true');
+INSERT INTO timezone VALUES('sj','Arctic/Longyearbyen','true');
+INSERT INTO timezone VALUES('tk','Pacific/Fakaofo','true');
+INSERT INTO timezone VALUES('to','Pacific/Tongatapu','true');
+INSERT INTO timezone VALUES('tv','Pacific/Funafuti','true');
+INSERT INTO timezone VALUES('us','Pacific/Honolulu','false');
+INSERT INTO timezone VALUES('vu','Pacific/Efate','true');
+INSERT INTO timezone VALUES('wf','Pacific/Wallis','true');
+INSERT INTO timezone VALUES('ws','Pacific/Apia','true');
+INSERT INTO timezone VALUES('cc','Indian/Cocos','true');
+INSERT INTO timezone VALUES('cx','Indian/Christmas','true');
+INSERT INTO timezone VALUES('io','Indian/Chagos','true');
+INSERT INTO timezone VALUES('km','Indian/Comoro','true');
+INSERT INTO timezone VALUES('mg','Indian/Antananarivo','true');
+INSERT INTO timezone VALUES('mu','Indian/Mauritius','true');
+INSERT INTO timezone VALUES('mv','Indian/Maldives','true');
+INSERT INTO timezone VALUES('sc','Indian/Mahe','true');
+INSERT INTO timezone VALUES('yt','Indian/Mayotte','true');
+INSERT INTO timezone VALUES('ad','Europe/Andorra','true');
+INSERT INTO timezone VALUES('al','Europe/Tirane','true');
+INSERT INTO timezone VALUES('at','Europe/Vienna','true');
+INSERT INTO timezone VALUES('ba','Europe/Sarajevo','true');
+INSERT INTO timezone VALUES('be','Europe/Brussels','true');
+INSERT INTO timezone VALUES('bg','Europe/Sofia','true');
+INSERT INTO timezone VALUES('by','Europe/Minsk','true');
+INSERT INTO timezone VALUES('ch','Europe/Zurich','true');
+INSERT INTO timezone VALUES('cz','Europe/Prague','true');
+INSERT INTO timezone VALUES('de','Europe/Berlin','true');
+INSERT INTO timezone VALUES('dk','Europe/Copenhagen','true');
+INSERT INTO timezone VALUES('ee','Europe/Tallinn','true');
+INSERT INTO timezone VALUES('es','Europe/Madrid','true');
+INSERT INTO timezone VALUES('fi','Europe/Helsinki','true');
+INSERT INTO timezone VALUES('fr','Europe/Paris','true');
+INSERT INTO timezone VALUES('gb','Europe/London','true');
+INSERT INTO timezone VALUES('gb','Europe/Belfast','false');
+INSERT INTO timezone VALUES('gi','Europe/Gibraltar','true');
+INSERT INTO timezone VALUES('gr','Europe/Athens','true');
+INSERT INTO timezone VALUES('hr','Europe/Zagreb','true');
+INSERT INTO timezone VALUES('hu','Europe/Budapest','true');
+INSERT INTO timezone VALUES('ie','Europe/Dublin','true');
+INSERT INTO timezone VALUES('it','Europe/Rome','true');
+INSERT INTO timezone VALUES('li','Europe/Vaduz','true');
+INSERT INTO timezone VALUES('lt','Europe/Vilnius','true');
+INSERT INTO timezone VALUES('lu','Europe/Luxembourg','true');
+INSERT INTO timezone VALUES('lv','Europe/Riga','true');
+INSERT INTO timezone VALUES('mc','Europe/Monaco','true');
+INSERT INTO timezone VALUES('md','Europe/Chisinau','true');
+INSERT INTO timezone VALUES('mk','Europe/Skopje','true');
+INSERT INTO timezone VALUES('mt','Europe/Malta','true');
+INSERT INTO timezone VALUES('nl','Europe/Amsterdam','true');
+INSERT INTO timezone VALUES('no','Europe/Oslo','true');
+INSERT INTO timezone VALUES('pl','Europe/Warsaw','true');
+INSERT INTO timezone VALUES('pt','Europe/Lisbon','true');
+INSERT INTO timezone VALUES('ro','Europe/Bucharest','true');
+INSERT INTO timezone VALUES('se','Europe/Stockholm','true');
+INSERT INTO timezone VALUES('si','Europe/Ljubljana','true');
+INSERT INTO timezone VALUES('sk','Europe/Bratislava','true');
+INSERT INTO timezone VALUES('sm','Europe/San_Marino','true');
+INSERT INTO timezone VALUES('tr','Europe/Istanbul','true');
+INSERT INTO timezone VALUES('ua','Europe/Kiev','true');
+INSERT INTO timezone VALUES('ua','Europe/Uzhgorod','false');
+INSERT INTO timezone VALUES('ua','Europe/Zaporozhye','false');
+INSERT INTO timezone VALUES('ua','Europe/Simferopol','false');
+INSERT INTO timezone VALUES('va','Europe/Vatican','true');
+INSERT INTO timezone VALUES('yu','Europe/Belgrade','true');
+INSERT INTO timezone VALUES('au','Australia/Lord_Howe','false');
+INSERT INTO timezone VALUES('au','Australia/Hobart','false');
+INSERT INTO timezone VALUES('au','Australia/Melbourne','false');
+INSERT INTO timezone VALUES('au','Australia/Sydney','true');
+INSERT INTO timezone VALUES('au','Australia/Broken_Hill','false');
+INSERT INTO timezone VALUES('au','Australia/Brisbane','false');
+INSERT INTO timezone VALUES('au','Australia/Lindeman','false');
+INSERT INTO timezone VALUES('au','Australia/Adelaide','false');
+INSERT INTO timezone VALUES('au','Australia/Darwin','false');
+INSERT INTO timezone VALUES('au','Australia/Perth','false');
+INSERT INTO timezone VALUES('ao','Africa/Luanda','true');
+INSERT INTO timezone VALUES('bf','Africa/Ouagadougou','true');
+INSERT INTO timezone VALUES('bi','Africa/Bujumbura','true');
+INSERT INTO timezone VALUES('bj','Africa/Porto-Novo','true');
+INSERT INTO timezone VALUES('bw','Africa/Gaborone','true');
+INSERT INTO timezone VALUES('cd','Africa/Kinshasa','true');
+INSERT INTO timezone VALUES('cd','Africa/Lubumbashi','false');
+INSERT INTO timezone VALUES('cf','Africa/Bangui','true');
+INSERT INTO timezone VALUES('cg','Africa/Brazzaville','true');
+INSERT INTO timezone VALUES('ci','Africa/Abidjan','true');
+INSERT INTO timezone VALUES('cm','Africa/Douala','true');
+INSERT INTO timezone VALUES('dj','Africa/Djibouti','true');
+INSERT INTO timezone VALUES('dz','Africa/Algiers','true');
+INSERT INTO timezone VALUES('eg','Africa/Cairo','true');
+INSERT INTO timezone VALUES('eh','Africa/El_Aaiun','true');
+INSERT INTO timezone VALUES('er','Africa/Asmera','true');
+INSERT INTO timezone VALUES('et','Africa/Addis_Ababa','true');
+INSERT INTO timezone VALUES('ga','Africa/Libreville','true');
+INSERT INTO timezone VALUES('gh','Africa/Accra','true');
+INSERT INTO timezone VALUES('gm','Africa/Banjul','true');
+INSERT INTO timezone VALUES('gn','Africa/Conakry','true');
+INSERT INTO timezone VALUES('gq','Africa/Malabo','true');
+INSERT INTO timezone VALUES('gw','Africa/Bissau','true');
+INSERT INTO timezone VALUES('ke','Africa/Nairobi','true');
+INSERT INTO timezone VALUES('lr','Africa/Monrovia','true');
+INSERT INTO timezone VALUES('ls','Africa/Maseru','true');
+INSERT INTO timezone VALUES('ly','Africa/Tripoli','true');
+INSERT INTO timezone VALUES('ma','Africa/Casablanca','true');
+INSERT INTO timezone VALUES('ml','Africa/Bamako','false');
+INSERT INTO timezone VALUES('ml','Africa/Timbuktu','true');
+INSERT INTO timezone VALUES('mr','Africa/Nouakchott','true');
+INSERT INTO timezone VALUES('mw','Africa/Blantyre','true');
+INSERT INTO timezone VALUES('mz','Africa/Maputo','true');
+INSERT INTO timezone VALUES('na','Africa/Windhoek','true');
+INSERT INTO timezone VALUES('ne','Africa/Niamey','true');
+INSERT INTO timezone VALUES('ng','Africa/Lagos','true');
+INSERT INTO timezone VALUES('rw','Africa/Kigali','true');
+INSERT INTO timezone VALUES('sd','Africa/Khartoum','true');
+INSERT INTO timezone VALUES('sl','Africa/Freetown','true');
+INSERT INTO timezone VALUES('sn','Africa/Dakar','true');
+INSERT INTO timezone VALUES('so','Africa/Mogadishu','true');
+INSERT INTO timezone VALUES('st','Africa/Sao_Tome','true');
+INSERT INTO timezone VALUES('sz','Africa/Mbabane','true');
+INSERT INTO timezone VALUES('td','Africa/Ndjamena','true');
+INSERT INTO timezone VALUES('tg','Africa/Lome','true');
+INSERT INTO timezone VALUES('tn','Africa/Tunis','true');
+INSERT INTO timezone VALUES('tz','Africa/Dar_es_Salaam','true');
+INSERT INTO timezone VALUES('ug','Africa/Kampala','true');
+INSERT INTO timezone VALUES('za','Africa/Johannesburg','true');
+INSERT INTO timezone VALUES('zm','Africa/Lusaka','true');
+INSERT INTO timezone VALUES('zw','Africa/Harare','true');
+INSERT INTO timezone VALUES('gl','America/Godthab','true');
+INSERT INTO timezone VALUES('mn','Asia/Ulaanbaatar','true');
+INSERT INTO timezone VALUES('um','Pacific/Johnston','false');
+INSERT INTO timezone VALUES('um','Pacific/Midway','true');
+INSERT INTO timezone VALUES('um','Pacific/Wake','false');
+COMMIT;
Added: trunk/Locale-Object/t/0_db.t
===================================================================
--- trunk/Locale-Object/t/0_db.t (rev 0)
+++ trunk/Locale-Object/t/0_db.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+
+use warnings::register;
+use strict;
+
+use Test::More tests => 3;
+
+use Locale::Object::DB;
+
+my $db = Locale::Object::DB->new();
+
+#1
+isa_ok( $db, 'Locale::Object::DB');
+
+my $result = $db->lookup(
+ table => 'country',
+ result_column => '*',
+ search_column => 'code_alpha2',
+ value => 'uz'
+ );
+
+my $code_alpha2 = @{$result}[0]->{'code_alpha2'};
+my $code_alpha3 = @{$result}[0]->{'code_alpha3'};
+my $code_numeric = @{$result}[0]->{'code_numeric'};
+my $name = @{$result}[0]->{'name'};
+my $name_native = @{$result}[0]->{'name_native'};
+my $main_timezone = @{$result}[0]->{'main_timezone'};
+my $uses_daylight_savings = @{$result}[0]->{'uses_daylight_savings'};
+
+#2
+is( $name, 'Uzbekistan', 'lookup was successful' );
+
+
+$result = $db->lookup_dual(
+ table => 'language_mappings',
+ result_col => 'official',
+ col_1 => 'country',
+ val_1 => 'gb',
+ col_2 => 'language',
+ val_2 => 'eng'
+ );
+
+#3
+is( @{$result}[0]->{'official'}, 'true', 'lookup_dual was successful' );
+
Added: trunk/Locale-Object/t/1_country.t
===================================================================
--- trunk/Locale-Object/t/1_country.t (rev 0)
+++ trunk/Locale-Object/t/1_country.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,84 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 17;
+
+use DateTime::TimeZone;
+use Locale::Object::Country;
+
+my $afghanistan = Locale::Object::Country->new( code_alpha2 => 'af' );
+
+#1
+isa_ok( $afghanistan, 'Locale::Object::Country' );
+
+#2
+is( $afghanistan->name, 'Afghanistan', 'it has the correct country name');
+
+#3
+is( $afghanistan->code_alpha3, 'afg', 'it has the correct 3-letter code');
+
+#4
+is( $afghanistan->code_numeric, '004', 'it has the correct numeric code');
+
+#5
+is( $afghanistan->dialing_code, '93', 'it has the right dialing code');
+
+#6
+is( $afghanistan->currency->name, 'afghani', 'it has the correct currency');
+
+#7
+is( $afghanistan->continent->name, 'Asia', "it's on the correct continent");
+
+my %countries;
+
+# Fill up a hash with the alpha2 codes of countries in the same continent
+foreach my $where ($afghanistan->continent->countries)
+{
+ # Get the alpha2 code of the country we're looking at.
+ my $where_code = $where->code_alpha2;
+ $countries{$where_code} = undef;
+}
+
+#8
+ok( exists $countries{'tj'}, 'it has a correct neighbor on its continent');
+
+my $copy = Locale::Object::Country->new( code_alpha2 => 'af' );
+
+#9
+is( $afghanistan->timezone->name, 'Asia/Kabul', 'it had the right timezone');
+
+#10
+ok( $copy eq $afghanistan, 'the object is a singleton');
+
+#11
+is( ($afghanistan->languages)[0]->name, 'Pushto', 'a correct language is spoken in it');
+
+#12
+is( ($afghanistan->languages_official)[0]->name, 'Pushto', 'the official language is correct');
+
+my ($wrong, $wrong_defined);
+
+{
+ # We can hide the warning, this is only a test.
+ local $SIG{__WARN__} = sub {};
+ eval {
+ $wrong = Locale::Object::Country->new( code_alpha2 => 'zz' );
+ };
+}
+
+defined $wrong ? $wrong_defined = 1 : $wrong_defined = 0;
+
+#13
+is( $wrong_defined, 0, 'an object was not made for an incorrect code' );
+
+my $britain = Locale::Object::Country->new( code_alpha2 => 'gb' );
+
+#14
+is( $britain->all_timezones->[0]->name, 'Europe/London', 'all timezones');
+is( $britain->all_timezones->[1]->name, DateTime::TimeZone->links->{'Europe/Belfast'}, 'belfast is a deprecated alias for London');
+
+ok( my $antarctica = Locale::Object::Country->new( code_alpha2 => 'aq' ), 'load Antarctica');
+
+ok( my $congo = Locale::Object::Country->new( code_alpha2 => 'cd' ), 'load Congo');
Added: trunk/Locale-Object/t/2_currency.t
===================================================================
--- trunk/Locale-Object/t/2_currency.t (rev 0)
+++ trunk/Locale-Object/t/2_currency.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 10;
+
+use Locale::Object::Currency;
+
+my $usd = Locale::Object::Currency->new( country_code => 'us' );
+
+#1
+isa_ok( $usd, 'Locale::Object::Currency' );
+
+#2
+is( $usd->name, 'dollar', 'it has the right name' );
+
+#3
+is( $usd->code, 'USD', 'it has the right code' );
+
+#4
+is( $usd->code_numeric, '840', 'it has the right numeric code' );
+
+#5
+is( $usd->symbol, '$', 'it has the right symbol' );
+
+#6
+is( $usd->subunit, 'cents', 'it has the right subunit' );
+
+#7
+is( $usd->subunit_amount, '100', 'it has the right subunit amount' );
+
+my @countries = @{$usd->countries};
+
+my $count = scalar @countries;
+
+#8
+is( $count, 12, 'the number of countries sharing it is correct' );
+
+# The code/name mapping of objects in %countries should be consistent with this.
+my %names = (
+ as => "American Samoa",
+ gu => "Guam",
+ pw => "Palau",
+ pr => "Puerto Rico",
+ tc => "Turks and Caicos Islands",
+ us => "United States",
+ vi => "Virgin Islands, U.S.",
+ vg => "Virgin Islands, British"
+ );
+
+my @places = keys %names;
+my $where = $places[rand @places];
+
+my $copy = Locale::Object::Currency->new( country_code => 'us' );
+
+#9
+ok( $copy eq $usd, 'the object is a singleton' );
+
+my ($wrong, $wrong_defined);
+
+{
+ # We can hide the warning, this is only a test.
+ local $SIG{__WARN__} = sub {};
+ eval {
+ $wrong = Locale::Object::Currency->new( code => 'xyz' );
+ };
+}
+
+defined $wrong ? $wrong_defined = 1 : $wrong_defined = 0;
+
+#10
+is( $wrong_defined, 0, 'an object was not made for an incorrect code' );
+
+# Remove __END__ to get a dump of the data structures created by this test.
+__END__
+print "\n==========================\n";
+print "| DATA STRUCTURE FOLLOWS |\n";
+print "==========================\n\n";
+
+use Data::Dumper;
+print Dumper $usd;
Added: trunk/Locale-Object/t/3_continent.t
===================================================================
--- trunk/Locale-Object/t/3_continent.t (rev 0)
+++ trunk/Locale-Object/t/3_continent.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 5;
+
+use Locale::Object::Continent;
+use Locale::Object::Country;
+
+my $asia = Locale::Object::Continent->new( name => 'Asia' );
+
+#1
+isa_ok( $asia, 'Locale::Object::Continent' );
+
+my $cont_name = $asia->name;
+
+#2
+is( $cont_name, 'Asia', 'it has the correct name' );
+
+#3
+is( scalar @{$asia->countries}, 47, 'it has the correct number of countries in it' );
+
+my %countries;
+
+# Fill up a hash with the alpha2 codes of countries in $asia.
+foreach my $where ($asia->countries)
+{
+ # Get the alpha2 code of the country we're looking at.
+ my $where_code = $where->code_alpha2;
+ $countries{$where_code} = undef;
+}
+
+#4
+ok( exists $countries{'af'}, 'a country in it has the right name' );
+
+my $copy = Locale::Object::Continent->new( name => 'Asia' );
+
+#5
+ok( $copy eq $asia, 'the object is a singleton' );
+
+# Remove __END__ to get a dump of the data structures created by this test.
+__END__
+print "\n==========================\n";
+print "| DATA STRUCTURE FOLLOWS |\n";
+print "==========================\n\n";
+
+use Data::Dumper;
+print Dumper $asia;
Added: trunk/Locale-Object/t/4_language.t
===================================================================
--- trunk/Locale-Object/t/4_language.t (rev 0)
+++ trunk/Locale-Object/t/4_language.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 8;
+
+use Locale::Object::Country;
+use Locale::Object::Language;
+
+my $eng = Locale::Object::Language->new( code_alpha2 => 'en' );
+
+#1
+isa_ok( $eng, 'Locale::Object::Language');
+
+#2
+is( $eng->name, 'English', 'it has the right name' );
+
+#3
+is( $eng->code_alpha3, 'eng', 'it has the right alpha3 code' );
+
+my @countries = @{$eng->countries};
+
+my $count = scalar @countries;
+
+#4
+is( $count, 86, 'the number of countries sharing it is correct' );
+
+my $copy = Locale::Object::Language->new( code_alpha2 => 'en' );
+
+#5
+ok( $copy eq $eng, 'the object is a singleton' );
+
+my $gb = Locale::Object::Country->new( code_alpha2 => 'gb' );
+my $wel = Locale::Object::Language->new( code_alpha3 => 'wel' );
+
+#6
+is( $eng->official($gb), 'true', "it's official in the correct country" );
+
+#7
+is( $wel->official($gb), 'false', "a secondary language isn't official" );
+
+my ($wrong, $wrong_defined);
+
+{
+ # We can hide the warning, this is only a test.
+ local $SIG{__WARN__} = sub {};
+ eval {
+ $wrong = Locale::Object::Language->new( code_alpha3 => 'XYZ' );
+ };
+}
+
+defined $wrong ? $wrong_defined = 1 : $wrong_defined = 0;
+
+#8
+is( $wrong_defined, 0, 'an object was not made for an incorrect code' );
+
+# Remove __END__ to get a dump of the data structures created by this test.
+__END__
+print "\n==========================\n";
+print "| DATA STRUCTURE FOLLOWS |\n";
+print "==========================\n\n";
+
+use Data::Dumper;
+print Dumper $eng;
Added: trunk/Locale-Object/t/5_object.t
===================================================================
--- trunk/Locale-Object/t/5_object.t (rev 0)
+++ trunk/Locale-Object/t/5_object.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,132 @@
+#!/usr/bin/perl
+
+use warnings::register;
+use strict;
+
+use Test::More tests => 18;
+
+use Locale::Object;
+
+my $obj = Locale::Object->new(
+ country_code_alpha2 => 'af',
+ currency_code => 'GBP',
+ language_code_alpha2 => 'en'
+ );
+
+#1
+isa_ok( $obj, 'Locale::Object' );
+
+# Country tests
+###############
+
+#2
+is( $obj->{_country}->name, 'Afghanistan', 'Set a country attribute with code_alpha2' );
+
+$obj->country_code_alpha3('kaz');
+
+#3
+is( $obj->{_country}->name, 'Kazakhstan', 'Reset country attribute with code_alpha3' );
+
+$obj->country_code_numeric(860);
+
+#4
+is( $obj->{_country}->name, 'Uzbekistan', 'Reset country attribute with code_numeric' );
+
+$obj->country_name('Kyrgyzstan');
+
+#5
+is( $obj->{_country}->code_numeric, 417, 'Reset country attribute with name' );
+
+# Currency tests
+################
+
+#6
+is( $obj->{_currency}->name, 'pound', 'Set currency attribute with code' );
+
+$obj->currency_code_numeric('004');
+
+#7
+is( $obj->{_currency}->name, 'afghani', 'Reset currency attribute with code_numeric' );
+
+# Language tests
+################
+
+#8
+is( $obj->{_language}->name, 'English', 'Set language attribute with code_alpha2' );
+
+$obj->language_code_alpha3('ara');
+
+#9
+is( $obj->{_language}->name, 'Arabic', 'Reset language attribute with code_alpha3' );
+
+$obj->language_name('Swedish');
+
+#10
+is( $obj->{_language}->code_alpha3, 'sve', 'Reset language attribute with name' );
+
+# Sanity checks
+###############
+
+#11
+is( $obj->sane('country'), 0, 'Object is addled according to country' );
+
+#12
+is( $obj->sane('currency'), 0, 'Object is addled according to currency' );
+
+#13
+is( $obj->sane('language'), 0, 'Object is addled according to language' );
+
+$obj->language_name('Swedish');
+$obj->country_name('United Kingdom');
+$obj->currency_code('LYD');
+
+$obj->make_sane(
+ populate => 1
+ );
+
+#14
+is( $obj->sane('country'), 1, 'Object was made sane without attribute parameter' );
+
+$obj->make_sane(
+ attribute => 'country',
+ );
+
+#15
+is( $obj->sane('country'), 1, 'Object was made sane by country' );
+
+$obj->language_name('Danish');
+$obj->country_name('Uganda');
+$obj->currency_code('IDR');
+
+$obj->make_sane(
+ attribute => 'language'
+ );
+
+#16
+is( $obj->sane('language'), 1, 'Object was made sane by language' );
+
+$obj->language_name('Dzongkha');
+$obj->currency_code('THB');
+$obj->empty('country');
+
+#17
+is( $obj->{_country}, undef, 'Emptying an attribute was successful' );
+
+$obj->make_sane(
+ attribute => 'currency'
+ );
+
+#18
+is( $obj->sane('currency'), 1, 'Object was made sane by currency' );
+
+$obj->language_name('Azerbaijani');
+$obj->country_name('Portugal');
+
+# Remove __END__ to get a dump of the data structures created by this test.
+__END__
+print "\n==========================\n";
+print "| DATA STRUCTURE FOLLOWS |\n";
+print "==========================\n\n";
+
+use Data::Dumper;
+print Dumper $obj;
Added: trunk/Locale-Object/t/6_convert.t
===================================================================
--- trunk/Locale-Object/t/6_convert.t (rev 0)
+++ trunk/Locale-Object/t/6_convert.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+use warnings::register;
+use strict;
+
+use Test::More tests => 8;
+
+use Locale::Object::Currency;
+use Locale::Object::Currency::Converter;
+
+my $usd = Locale::Object::Currency->new( code => 'USD' );
+my $gbp = Locale::Object::Currency->new( code => 'GBP' );
+my $eur = Locale::Object::Currency->new( code => 'EUR' );
+my $jpy = Locale::Object::Currency->new( code => 'JPY' );
+
+my $converter = Locale::Object::Currency::Converter->new(
+ from => $usd,
+ to => $gbp,
+ service => 'XE'
+ );
+
+#1
+isa_ok( $converter, 'Locale::Object::Currency::Converter');
+
+my $amount = 5;
+
+# "Test" a conversion - output a test result, but don't fail if it
+# doesn't work. This is because Finance::Currency::Convert::XE and
+# Finance::Currency::Convert::Yahoo occasionally don't work due to transient
+# network conditions. We want to indicate success/failure but not actually
+# kill the tests.
+
+# We can hide any warnings (like the ones Finance::Currency::Convert::XE chucks
+# out from time to time about a currency not being available) - this is only a test.
+local $SIG{__WARN__} = sub {};
+
+SKIP:
+{
+ skip 'Finance::Currency::Convert::XE not installed', 1 unless $converter->use_xe == 1;
+
+ my $result = $converter->convert($amount);
+
+ #2
+ if (defined $result && $result !~ /ERROR/)
+ {
+ pass('An XE conversion worked');
+ }
+ else
+ {
+ pass('An XE conversion was not successful, this may be due to transient network conditions');
+ }
+}
+
+#3
+ok( $converter->service('Yahoo'), 'Resetting currency service worked' );
+
+#4
+ok( $converter->from($eur), "Resetting 'from' currency worked" );
+
+#5
+ok( $converter->to($jpy), "Resetting 'to' currency worked" );
+
+SKIP:
+{
+ skip 'Finance::Currency::Convert::Yahoo not installed', 1 unless $converter->use_yahoo == 1;
+
+ my $result = $converter->convert($amount);
+
+ # More "tests" - see note above.
+
+ #6
+ if (defined $result && $result !~ /ERROR/)
+ {
+ pass('A Yahoo! conversion worked');
+ }
+ else
+ {
+ pass('A Yahoo! conversion was not successful, this may be due to transient network conditions');
+ }
+}
+
+my $rate = $converter->rate;
+
+#7
+if (defined $rate)
+{
+ pass('A conversion rate was found');
+}
+else
+{
+ pass('A conversion rate was not found, this may be due to transient network conditions');
+}
+
+my $timestamp = $converter->timestamp;
+
+#8
+if (defined $timestamp)
+{
+ pass('A rate timestamp was found');
+}
+else
+{
+ pass('A rate timestamp was not found, this may be due to transient network conditions');
+}
+
Added: trunk/Locale-Object/t/meta_pod.t
===================================================================
--- trunk/Locale-Object/t/meta_pod.t (rev 0)
+++ trunk/Locale-Object/t/meta_pod.t 2007-09-21 13:38:11 UTC (rev 3771)
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use vars qw(@classes);
+use lib 'lib';
+
+BEGIN {
+ eval { require File::Find::Rule; };
+ if ($@) {
+ print "1..0 # Skipped - do not have File::Find::Rule installed\n";
+ exit;
+ }
+}
+
+BEGIN {
+ use File::Find::Rule;
+ @classes = File::Find::Rule->file()->name('*.pm')->in('blib/lib');
+}
+
+use Test::Pod tests => scalar @classes;
+
+foreach my $class (@classes) {
+ pod_file_ok($class);
+}
More information about the Bast-commits
mailing list