The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 125
META.json 22
META.yml 2222
lib/Rose/DB/Object/Helpers.pm 32
lib/Rose/DB/Object/MakeMethods/Generic.pm 440
lib/Rose/DB/Object/Manager.pm 715
lib/Rose/DB/Object/Metadata/Auto/Pg.pm 111
lib/Rose/DB/Object/Metadata/Column/Numeric.pm 49
lib/Rose/DB/Object/Tutorial.pod 66
lib/Rose/DB/Object.pm 11
t/db-object-auto.t 11
t/db-object-loader.t 11
t/db-object-manager.t 670
t/db-object-relationship.t 913
t/make-modules.t 11
15 files changed (This is a version diff) 69219
@@ -1,4 +1,28 @@
-0.810 (01.18.2013) - John Siracusa <siracusa@gmail.com>
+0.813 (11.07.2014) - John Siracusa <siracusa@gmail.com>
+
+    * Added prepare_options parameter to get_objects_iterator_from_sql() and
+      get_objects_from_sql() Manager methods (RT 98014)
+
+0.812 (11.07.2014) - John Siracusa <siracusa@gmail.com>
+
+    * Second attempt to address precision and scale mix-ups in auto-loaded
+      numeric column metadata.
+    * Fixed get_objects_count() with custom select lists and distinct
+      (Reported by Alexander Karelas)
+    * Fixed precision and scale references in the tutorial (RT 96079)
+    * Fixed an incorrect method name in the Rose::DB::Object::Helpers
+      documentation (RT 97602)
+    * Fixed a bug where save() parameters were not passed to map record
+      save() calls (RT 98730)
+    * Corrected a typo in the documentation (RT 94100)
+    * Updated tests to work with DBD::Pg versions greater than 2.x.x.
+
+0.811 (03.21.2014) - John Siracusa <siracusa@gmail.com>
+
+    * Fixed a bug that prevented many-to-many map records from being saved
+      to the database (RT 93531)
+
+0.810 (01.18.2014) - John Siracusa <siracusa@gmail.com>
 
     * Improved automated installation detection (RT 92255)
 
@@ -4,7 +4,7 @@
       "John Siracusa <siracusa@gmail.com>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380",
+   "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141170",
    "license" : [
       "perl_5"
    ],
@@ -66,5 +66,5 @@
       },
       "x_MailingList" : "http://groups.google.com/group/rose-db-object"
    },
-   "version" : "0.810"
+   "version" : "0.813"
 }
@@ -3,42 +3,42 @@ abstract: 'Extensible, high performance object-relational mapper (ORM).'
 author:
   - 'John Siracusa <siracusa@gmail.com>'
 build_requires:
-  ExtUtils::MakeMaker: 0
+  ExtUtils::MakeMaker: '0'
 configure_requires:
-  ExtUtils::MakeMaker: 0
+  ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380'
+generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.141170'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: Rose-DB-Object
 no_index:
   directory:
     - t
     - inc
 requires:
-  Bit::Vector: 0
-  Clone: 0.29
-  Cwd: 0
-  DBI: 1.40
-  Data::Dumper: 2.121
-  DateTime: 0
-  File::Path: 0
-  File::Spec: 0
-  List::MoreUtils: 0
-  Math::BigInt: 1.77
-  Rose::DB: 0.763
-  Rose::DateTime::Util: 0.532
-  Rose::Object: 0.854
-  Scalar::Util: 0
-  Test::More: 0
-  Time::Clock: 1.00
-  perl: 5.006000
+  Bit::Vector: '0'
+  Clone: '0.29'
+  Cwd: '0'
+  DBI: '1.40'
+  Data::Dumper: '2.121'
+  DateTime: '0'
+  File::Path: '0'
+  File::Spec: '0'
+  List::MoreUtils: '0'
+  Math::BigInt: '1.77'
+  Rose::DB: '0.763'
+  Rose::DateTime::Util: '0.532'
+  Rose::Object: '0.854'
+  Scalar::Util: '0'
+  Test::More: '0'
+  Time::Clock: '1.00'
+  perl: '5.006000'
 resources:
   MailingList: http://groups.google.com/group/rose-db-object
   bugtracker: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-DB-Object
   homepage: http://rose.googlecode.com/
   license: http://dev.perl.org/licenses/
   repository: http://rose.googlecode.com/svn/trunk/modules/Rose-DB-Object
-version: 0.810
+version: '0.813'
@@ -11,7 +11,7 @@ require Rose::DB::Object::Util;
 
 use Carp;
 
-our $VERSION = '0.784';
+our $VERSION = '0.812';
 
 __PACKAGE__->export_tags
 (
@@ -1360,8 +1360,7 @@ Example:
 
     # Get person id 123 if it exists, otherwise create it now
     # along with permission sub-objects.
-    $person = Person->new(id    => 123, 
-                          perms => \@perms)->load_or_insert;
+    $person = Person->new(id => 123, perms => \@perms)->load_or_save;
 
 =head2 load_speculative [PARAMS]
 
@@ -20,7 +20,7 @@ use Rose::DB::Object::Constants
 use Rose::DB::Object::Helpers();
 use Rose::DB::Object::Util qw(column_value_formatted_key);
 
-our $VERSION = '0.784';
+our $VERSION = '0.812';
 
 our $Debug = 0;
 
@@ -5149,7 +5149,25 @@ sub objects_by_map
               # Create or retrieve map record, connected to self
               if($map_record_method)
               {
-                $map_record = $object->$map_record_method() || $map_class->new;
+                $map_record = $object->$map_record_method();
+
+                if($map_record)
+                {
+                  if($map_record->{STATE_IN_DB()})
+                  {
+                    foreach my $method ($map_record->meta->primary_key_column_mutator_names)
+                    {
+                      $map_record->$method(undef);
+                    }
+
+                    $map_record->{STATE_IN_DB()} = 0;
+                  }
+                }
+                else
+                {
+                  $map_record = $map_class->new;
+                }
+
                 $map_record->init(%method_map_to_self, db => $db);
               }
               else
@@ -5421,7 +5439,25 @@ sub objects_by_map
             # Create or retrieve map record, connected to self
             if($map_record_method)
             {
-              $map_record = $object->$map_record_method() || $map_class->new;
+              $map_record = $object->$map_record_method();
+
+              if($map_record)
+              {
+                if($map_record->{STATE_IN_DB()})
+                {
+                  foreach my $method ($map_record->meta->primary_key_column_mutator_names)
+                  {
+                    $map_record->$method(undef);
+                  }
+
+                  $map_record->{STATE_IN_DB()} = 0;
+                }
+              }
+              else
+              {
+                $map_record = $map_class->new;
+              }
+
               $map_record->init(%method_map_to_self, db => $db);
             }
             else
@@ -5467,7 +5503,7 @@ sub objects_by_map
             # Save the map record, if necessary
             unless($in_db)
             {
-              $map_record->save or die $map_record->error;
+              $map_record->save(%$args) or die $map_record->error;
             }
           }
 
@@ -16,7 +16,7 @@ use Rose::DB::Object::Constants
 # XXX: A value that is unlikely to exist in a primary key column value
 use constant PK_JOIN => "\0\2,\3\0";
 
-our $VERSION = '0.790';
+our $VERSION = '0.813';
 
 our $Debug = 0;
 
@@ -1650,7 +1650,7 @@ sub get_objects
     my($sql, $bind, @bind_params);
 
     # Do we have to use DISTINCT to count?
-    my $use_distinct = $with_objects ? 1 : 0;
+    my $use_distinct = (delete $args{'distinct'} || $with_objects) ? 1 : 0;
 
     if(!$use_distinct && $require_objects)
     {
@@ -1679,8 +1679,10 @@ sub get_objects
       if(!$use_distinct || @$pk_columns == 1 || 
          $db->supports_multi_column_count_distinct)
       {
+        my $select_arg = delete $args{'select'};
+
         $select = $use_distinct ? 
-          'COUNT(DISTINCT ' . join(', ', map { "t1.$_" } @$pk_columns) . ')' :
+          'COUNT(DISTINCT ' .  join(', ', ($select_arg ? @$select_arg : (map { "t1.$_" } @$pk_columns))) . ')' :
           'COUNT(*)';
       }
       else
@@ -3462,6 +3464,7 @@ sub get_objects_from_sql
 
   my $methods   = $args{'_methods'};
   my $exec_args = $args{'args'} || [];
+  my $attr      = $args{'prepare_options'};
 
   my $have_methods = ($args{'_methods'} && %{$args{'_methods'}}) ? 1 : 0;
 
@@ -3497,8 +3500,8 @@ sub get_objects_from_sql
       local $dbh->{'RaiseError'} = 1;
 
       $Debug && warn "$sql (", join(', ', @$exec_args), ")\n";
-      my $sth = $prepare_cached ? $dbh->prepare_cached($sql, undef, 3) : 
-                                  $dbh->prepare($sql) or die $dbh->errstr;
+      my $sth = $prepare_cached ? $dbh->prepare_cached($sql, $attr, 3) : 
+                                  $dbh->prepare($sql, $attr) or die $dbh->errstr;
 
       $sth->execute(@$exec_args);
 
@@ -3589,6 +3592,7 @@ sub get_objects_iterator_from_sql
 
   my $methods   = $args{'_methods'};
   my $exec_args = $args{'args'} || [];
+  my $attr      = $args{'prepare_options'};
 
   my $have_methods = ($args{'_methods'} && %{$args{'_methods'}}) ? 1 : 0;
 
@@ -3624,8 +3628,8 @@ sub get_objects_iterator_from_sql
       local $dbh->{'RaiseError'} = 1;
 
       $Debug && warn "$sql (", join(', ', @$exec_args), ")\n";
-      $sth = $prepare_cached ? $dbh->prepare_cached($sql, undef, 3) : 
-                               $dbh->prepare($sql) or die $dbh->errstr;
+      $sth = $prepare_cached ? $dbh->prepare_cached($sql, $attr, 3) : 
+                               $dbh->prepare($sql, $attr) or die $dbh->errstr;
 
       $sth->execute(@$exec_args);
     };
@@ -4694,6 +4698,10 @@ The class name of the L<Rose::DB::Object>-derived objects to be fetched.  Defaul
 
 If true, then L<DBI>'s L<prepare_cached|DBI/prepare_cached> method will be used (instead of the L<prepare|DBI/prepare> method) when preparing the SQL statement that will fetch the objects.  If omitted, the default value is determined by the L<dbi_prepare_cached|/dbi_prepare_cached> class method.
 
+=item B<prepare_options HASHREF>
+
+A reference to a hash of attributes to be passed to L<DBI>'s L<prepare|DBI/prepare> or L<prepare_cached|DBI/prepare_cached> method when preparing the SQL statement.
+
 =item B<share_db BOOL>
 
 If true, C<db> will be passed to each L<Rose::DB::Object>-derived object when it is constructed.  Defaults to true.
@@ -11,7 +11,7 @@ our @ISA = qw(Rose::DB::Object::Metadata::Auto);
 
 our $Debug;
 
-our $VERSION = '0.784';
+our $VERSION = '0.812';
 
 # Other useful columns, not selected for now
 #   pg_get_indexdef(i.oid) AS indexdef
@@ -159,4 +159,14 @@ sub auto_generate_unique_keys
   return wantarray ? @unique_keys : \@unique_keys;
 }
 
+sub auto_generate_column
+{
+  my($self, $name, $col_info) = @_;
+
+  $col_info->{'NUMERIC_PRECISION'} = $col_info->{'DECIMAL_DIGITS'};
+  $col_info->{'NUMERIC_SCALE'}     = $col_info->{'COLUMN_SIZE'};
+
+  return $self->SUPER::auto_generate_column($name, $col_info);
+}
+
 1;
@@ -7,7 +7,7 @@ use Rose::Object::MakeMethods::Generic;
 use Rose::DB::Object::Metadata::Column::Scalar;
 our @ISA = qw(Rose::DB::Object::Metadata::Column::Scalar);
 
-our $VERSION = '0.788';
+our $VERSION = '0.812';
 
 __PACKAGE__->delete_common_method_maker_argument_names('length');
 
@@ -35,10 +35,15 @@ sub should_inline_value
 sub init_with_dbi_column_info
 {
   my($self, $col_info) = @_;
-$DB::single = 1;
+
+  $self->precision(defined $col_info->{'NUMERIC_PRECISION'} ? 
+    $col_info->{'NUMERIC_PRECISION'} : $col_info->{'COLUMN_SIZE'});
+
+  $self->scale(defined $col_info->{'NUMERIC_SCALE'} ? 
+    $col_info->{'NUMERIC_SCALE'} : $col_info->{'DECIMAL_DIGITS'});
+
   # Prevent COLUMN_SIZE from setting bogus length in superclass
-  $self->precision($col_info->{'DECIMAL_DIGITS'});
-  $self->scale(delete $col_info->{'COLUMN_SIZE'});
+  delete $col_info->{'COLUMN_SIZE'};
 
   $self->SUPER::init_with_dbi_column_info($col_info);
 
@@ -260,7 +260,7 @@ The examples above show SELECT, INSERT, UPDATE, and DELETE operations on one row
 
 But why is there a separate class for dealing with multiple objects?  Why not simply add more methods to the object itself?  Say, a C<search()> method to go alongside L<load()|Rose::DB::Object/load>, L<save()|Rose::DB::Object/save>, L<delete()|Rose::DB::Object/delete> and friends?  There are several reasons.
 
-First, it's somewhat "semantically impure" for the class that represents a single row to also be the class that's used to fetch multiple row.  It's also important to keep the object method namespace as sparsely populated as possible.  Each new object method prevents a column with the same name from using that method name.  L<Rose::DB::Object> tries to keep the list of L<reserved method names|Rose::DB::Object/"RESERVED METHODS"> as small as possible.
+First, it's somewhat "semantically impure" for the class that represents a single row to also be the class that's used to fetch multiple rows.  It's also important to keep the object method namespace as sparsely populated as possible.  Each new object method prevents a column with the same name from using that method name.  L<Rose::DB::Object> tries to keep the list of L<reserved method names|Rose::DB::Object/"RESERVED METHODS"> as small as possible.
 
 Second, inevitably, classes grow.  It's important for the object manager class to be separate from the object class itself so each class can grow happily in isolation, with no potential for namespace or functionality clashes.
 
@@ -714,7 +714,7 @@ Here's the output of that print statement.  A few long lines were manually wrapp
       id           => { type => 'integer', not_null => 1 },
       name         => { type => 'varchar', length => 255, not_null => 1 },
       price        => { type => 'numeric', default => '0.00', 
-                        not_null => 1, precision => 2, scale => 10 },
+                        not_null => 1, precision => 10, scale => 2 },
       vendor_id    => { type => 'integer' },
       status       => { type => 'varchar', default => 'inactive', 
                         length => 128, not_null => 1 },
@@ -805,7 +805,7 @@ Finally, here's how the foreign key definition looks in the Perl class.
         id           => { type => 'integer', not_null => 1 },
         name         => { type => 'varchar', length => 255, not_null => 1 },
         price        => { type => 'numeric', default => '0.00', 
-                          not_null => 1, precision => 2, scale => 10 },
+                          not_null => 1, precision => 10, scale => 2 },
         vendor_id    => { type => 'integer' },
         status       => { type => 'varchar', default => 'inactive', 
                           length => 128, not_null => 1 },
@@ -972,7 +972,7 @@ Here's the output.
       id           => { type => 'integer', not_null => 1 },
       name         => { type => 'varchar', length => 255, not_null => 1 },
       price        => { type => 'numeric', default => '0.00', 
-                        not_null => 1, precision => 2, scale => 10 },
+                        not_null => 1, precision => 10, scale => 2 },
       vendor_id    => { type => 'integer' },
       status       => { type => 'varchar', default => 'inactive', 
                         length => 128, not_null => 1 },
@@ -1916,7 +1916,7 @@ The code created by the loader is shown below.  Compare it to the manually creat
       region     => { type => 'character', default => 'US', length => 2, 
                        not_null => 1 },
       price      => { type => 'numeric', default => '0.00', not_null => 1,
-                      precision => 2, scale => 10 },
+                      precision => 10, scale => 2 },
     ],
 
     primary_key_columns => [ 'id' ],
@@ -2053,7 +2053,7 @@ The code created by the loader is shown below.  Compare it to the manually creat
       id           => { type => 'integer', not_null => 1 },
       name         => { type => 'varchar', length => 255, not_null => 1 },
       price        => { type => 'numeric', default => '0.00', not_null => 1, 
-                        precision => 2, scale => 10 },
+                        precision => 10, scale => 2 },
       vendor_id    => { type => 'integer' },
       status       => { type => 'varchar', default => 'inactive', 
                         length => 128, not_null => 1 },
@@ -16,7 +16,7 @@ use Rose::DB::Constants qw(IN_TRANSACTION);
 use Rose::DB::Object::Exception;
 use Rose::DB::Object::Util();
 
-our $VERSION = '0.810';
+our $VERSION = '0.813';
 
 our $Debug = 0;
 
@@ -305,7 +305,7 @@ EOF
 
   my($v1, $v2, $v3) = split(/\./, $DBD::Pg::VERSION);
 
-  if($v1 >= 2 && $v2 >= 19)
+  if(($v1 >= 2 && $v2 >= 19) || $v1 > 2)
   {
     is(MyPgObject->meta->perl_unique_keys_definition(style => 'object', braces => 'bsd', indent => 2),
       <<'EOF', "perl_unique_keys_definition 2 - $db_type");
@@ -235,7 +235,7 @@ foreach my $db_type (qw(mysql pg pg_with_schema informix sqlite oracle))
     SKIP: { skip("bigserial test for $db_type", 1) }
   }
 
-  if($db_type eq 'Pg')
+  if($db_type eq 'Pg' || $db_type eq 'mysql')
   {
     is($price_class->meta->column('price')->precision, 10, "decimal precision - $db_type");
     is($price_class->meta->column('price')->scale, 2, "decimal scale - $db_type");
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests => 3910;
+use Test::More tests => 3917;
 
 BEGIN 
 {
@@ -93,7 +93,7 @@ if(defined $ENV{'RDBO_NESTED_JOINS'} && Rose::DB::Object::Manager->can('default_
 
 SKIP: foreach my $db_type (qw(pg)) #pg_with_schema
 {
-  skip("PostgreSQL tests", 784)  unless($HAVE_PG);
+  skip("PostgreSQL tests", 787)  unless($HAVE_PG);
 
   Rose::DB->default_type($db_type);
 
@@ -336,6 +336,22 @@ SKIP: foreach my $db_type (qw(pg)) #pg_with_schema
 
   is($count, 1, "get_objects_count() require 1 - $db_type");
 
+  $count = MyPgObjectManager->object_count(
+    select   => 'name',
+    distinct => 1,
+    all      => 1,
+  );
+
+  is($count, 4, "get_objects_count() distinct column 1 - $db_type");
+
+  $count = MyPgObjectManager->object_count(
+    select   => [ 'status' ],
+    distinct => 1,
+    all      => 1,
+  );
+
+  is($count, 1, "get_objects_count() distinct column 2 - $db_type");
+
   # Clear sub-object
   $objs->[0]->b1(undef);
   $objs->[0]->save;
@@ -2315,13 +2331,27 @@ EOF
     MyPgObjectManager->get_objects_from_sql(
       db   => $db,
       args => [ 19 ],
-      sql => <<"EOF");
-SELECT * FROM rose_db_object_test WHERE id > ? ORDER BY id DESC
+      prepare_options => { pg_placeholder_dollaronly => 1 },
+      sql => <<'EOF');
+SELECT * FROM rose_db_object_test WHERE id > $1 ORDER BY id DESC
 EOF
 
   ok(scalar @$objs == 2, "get_objects_from_sql 9 - $db_type");
   is($objs->[0]->id, 60, "get_objects_from_sql 10 - $db_type");
 
+  $iterator = 
+    MyPgObjectManager->get_objects_iterator_from_sql(
+      db   => $db,
+      args => [ 19 ],
+      prepare_options => { pg_placeholder_dollaronly => 1 },
+      sql => <<'EOF');
+SELECT * FROM rose_db_object_test WHERE id > $1 ORDER BY id DESC
+EOF
+
+  $o = $iterator->next;
+  is($o->id, 60, "get_objects_iterator_from_sql 11 - $db_type");
+  $iterator->finish();
+
   my $method = 
     MyPgObjectManager->make_manager_method_from_sql(
       get_em => <<"EOF");
@@ -3131,7 +3161,7 @@ EOF
 
 SKIP: foreach my $db_type ('mysql')
 {
-  skip("MySQL tests", 791)  unless($HAVE_MYSQL);
+  skip("MySQL tests", 793)  unless($HAVE_MYSQL);
 
   Rose::DB->default_type($db_type);
 
@@ -3372,6 +3402,24 @@ SKIP: foreach my $db_type ('mysql')
 
   is($count, 1, "get_objects_count() require 1 - $db_type");
 
+  $count = Rose::DB::Object::Manager->get_objects_count(
+    object_class => 'MyMySQLObject',
+    select       => 'name',
+    distinct     => 1,
+    all          => 1,
+  );
+
+  is($count, 4, "get_objects_count() distinct column 1 - $db_type");
+
+  $count = Rose::DB::Object::Manager->get_objects_count(
+    object_class => 'MyMySQLObject',
+    select       => [ 'status' ],
+    distinct     => 1,
+    all          => 1,
+  );
+
+  is($count, 1, "get_objects_count() distinct column 2 - $db_type");
+
   # Clear sub-object
   $objs->[0]->b1(undef);
   $objs->[0]->save;
@@ -8913,7 +8961,7 @@ EOF
 
 SKIP: foreach my $db_type (qw(sqlite))
 {
-  skip("SQLite tests", 794)  unless($HAVE_SQLITE);
+  skip("SQLite tests", 796)  unless($HAVE_SQLITE);
 
   Rose::DB->default_type($db_type);
 
@@ -9231,6 +9279,22 @@ SKIP: foreach my $db_type (qw(sqlite))
 
   is($count, 1, "get_objects_count() require 1 - $db_type");
 
+  $count = MySQLiteObjectManager->object_count(
+    select   => 'name',
+    distinct => 1,
+    all      => 1,
+  );
+
+  is($count, 4, "get_objects_count() distinct column 1 - $db_type");
+
+  $count = MySQLiteObjectManager->object_count(
+    select   => [ 'status' ],
+    distinct => 1,
+    all      => 1,
+  );
+
+  is($count, 1, "get_objects_count() distinct column 2 - $db_type");
+
   # Clear sub-object
   $objs->[0]->b1(undef);
   $objs->[0]->save;
@@ -2,7 +2,7 @@
 
 use strict;
 
-use Test::More tests => 1603;
+use Test::More tests => 1604;
 
 BEGIN 
 {
@@ -4523,7 +4523,7 @@ SKIP: foreach my $db_type ('informix')
 
 SKIP: foreach my $db_type ('sqlite')
 {
-  skip("SQLite tests", 465)  unless($HAVE_SQLITE);
+  skip("SQLite tests", 466)  unless($HAVE_SQLITE);
 
   Rose::DB->default_type($db_type);
 
@@ -6125,22 +6125,26 @@ SKIP: foreach my $db_type ('sqlite')
   # Begin with_map_records tests
 
   test_memory_cycle_ok($o, "with_map_records memory cycle 1 - $db_type");
-# print find_cycle($o);
-# print "######################\n";
-#$DB::single = 1;
+
   @colors = $o->colors2;  
-# use Devel::Cycle;
-# print find_cycle($o);
-# exit;
+
   is($colors[0]->map_record->color_id, $colors[0]->id, "with_map_records rel 1 - $db_type");
   is($colors[0]->map_record->obj_id, $o->id, "with_map_records rel 2 - $db_type");
-#exit;
+
   @colors = $o->colors3;  
 
   is($colors[-1]->map_rec->color_id, $colors[-1]->id, "with_map_records rel 3 - $db_type");
   is($colors[-1]->map_rec->obj_id, $o->id, "with_map_records rel 4 - $db_type");
   is($colors[-1]->map_rec->color_id, 1, "with_map_records rel 5 - $db_type");
 
+  $colors[-1]->map_rec->arb_attr('new');
+
+  $o->colors3(@colors);
+  $o->save;
+
+  $o2 = ref($o)->new(id => $o->id)->load;
+  is(join(',', sort map { $_->id } $o2->colors), join(',', sort map { $_->id } @colors), "with_map_records update 1 - $db_type");
+
   my $objs = 
     Rose::DB::Object::Manager->get_objects(
       object_class => 'MySQLiteObject',
@@ -119,7 +119,7 @@ foreach my $db_type (qw(pg mysql informix sqlite))
   no warnings 'uninitialized';
   my($v1, $v2, $v3) = split(/\./, $DBD::Pg::VERSION);
 
-  if($db_type eq 'pg' && $v1 >= 2 && $v2 >= 19)
+  if($db_type eq 'pg' && (($v1 >= 2 && $v2 >= 19) || $v1 > 2))
   {
     $unique_keys = qq([ 'name' ],\n    [ 'name', 'vendor_id' ],);
   }