Hello community,

here is the log from the commit of package perl-Data-ObjectDriver for 
openSUSE:Factory checked in at 2020-10-30 11:58:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Data-ObjectDriver (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Data-ObjectDriver.new.3463 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Data-ObjectDriver"

Fri Oct 30 11:58:57 2020 rev:6 rq:845001 version:0.21

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/perl-Data-ObjectDriver/perl-Data-ObjectDriver.changes
    2020-09-15 16:35:03.510985588 +0200
+++ 
/work/SRC/openSUSE:Factory/.perl-Data-ObjectDriver.new.3463/perl-Data-ObjectDriver.changes
  2020-10-30 11:58:58.802308396 +0100
@@ -1,0 +2,6 @@
+Fri Oct 30 03:07:06 UTC 2020 - Tina Müller <[email protected]>
+
+- updated to 0.21
+   see /usr/share/doc/packages/perl-Data-ObjectDriver/Changes
+
+-------------------------------------------------------------------

Old:
----
  Data-ObjectDriver-0.20.tar.gz

New:
----
  Data-ObjectDriver-0.21.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Data-ObjectDriver.spec ++++++
--- /var/tmp/diff_new_pack.yQ05Si/_old  2020-10-30 11:58:59.326308861 +0100
+++ /var/tmp/diff_new_pack.yQ05Si/_new  2020-10-30 11:58:59.330308865 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           perl-Data-ObjectDriver
-Version:        0.20
+Version:        0.21
 Release:        0
 %define cpan_name Data-ObjectDriver
 Summary:        Simple, transparent data interface, with caching

++++++ Data-ObjectDriver-0.20.tar.gz -> Data-ObjectDriver-0.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/Changes 
new/Data-ObjectDriver-0.21/Changes
--- old/Data-ObjectDriver-0.20/Changes  2020-09-14 14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/Changes  2020-10-29 06:58:38.000000000 +0100
@@ -1,4 +1,9 @@
-0.20 2020-09-14T12:19:30Z
+0.21 2020-10-29T05:58:31Z
+
+0.21 2020-10-29T05:54:05Z
+    - Add GitHub Actions #38
+    - Support DBD::MariaDB #39
+    - Fork safety #40
 
 0.20 2020-09-14T12:15:54Z
     - Fix tests (Thanks to eseyman) #36
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/MANIFEST 
new/Data-ObjectDriver-0.21/MANIFEST
--- old/Data-ObjectDriver-0.20/MANIFEST 2020-09-14 14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/MANIFEST 2020-10-29 06:58:38.000000000 +0100
@@ -14,6 +14,7 @@
 lib/Data/ObjectDriver/Driver/Cache/Memcached.pm
 lib/Data/ObjectDriver/Driver/Cache/RAM.pm
 lib/Data/ObjectDriver/Driver/DBD.pm
+lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm
 lib/Data/ObjectDriver/Driver/DBD/Oracle.pm
 lib/Data/ObjectDriver/Driver/DBD/Pg.pm
 lib/Data/ObjectDriver/Driver/DBD/SQLite.pm
@@ -54,6 +55,7 @@
 t/41-callbacks.t
 t/42-callbacks-multi-pk.t
 t/50-profiling.t
+t/60-fork.t
 t/lib/Cache/Memory.pm
 t/lib/DodTestUtil.pm
 t/lib/ErrorTest.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/META.json 
new/Data-ObjectDriver-0.21/META.json
--- old/Data-ObjectDriver-0.20/META.json        2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/META.json        2020-10-29 06:58:38.000000000 
+0100
@@ -4,7 +4,7 @@
       "-2006"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Minilla/v3.1.10",
+   "generated_by" : "Minilla/v3.1.11",
    "license" : [
       "perl_5"
    ],
@@ -25,6 +25,68 @@
          "builder"
       ]
    },
+   "optional_features" : {
+      "test_fork" : {
+         "description" : "Test Fork",
+         "prereqs" : {
+            "runtime" : {
+               "requires" : {
+                  "DBI" : "1.614",
+                  "POSIX::AtFork" : "0",
+                  "Parallel::ForkManager" : "0",
+                  "Scalar::Util" : "0",
+                  "Test::SharedFork" : "0"
+               }
+            }
+         }
+      },
+      "test_mariadb" : {
+         "description" : "Test MariaDB",
+         "prereqs" : {
+            "runtime" : {
+               "requires" : {
+                  "DBD::MariaDB" : "0",
+                  "SQL::Translator" : "0",
+                  "Test::mysqld" : "0"
+               }
+            }
+         }
+      },
+      "test_mysql" : {
+         "description" : "Test MySQL",
+         "prereqs" : {
+            "runtime" : {
+               "requires" : {
+                  "DBD::mysql" : "0",
+                  "SQL::Translator" : "0",
+                  "Test::mysqld" : "0"
+               }
+            }
+         }
+      },
+      "test_postgresql" : {
+         "description" : "Test PostgreSQL",
+         "prereqs" : {
+            "runtime" : {
+               "requires" : {
+                  "DBD::Pg" : "0",
+                  "SQL::Translator" : "0",
+                  "Test::PostgreSQL" : "0"
+               }
+            }
+         }
+      },
+      "test_sqlite" : {
+         "description" : "Test SQLite",
+         "prereqs" : {
+            "runtime" : {
+               "requires" : {
+                  "DBD::SQLite" : "0"
+               }
+            }
+         }
+      }
+   },
    "prereqs" : {
       "build" : {
          "requires" : {
@@ -70,7 +132,7 @@
    "provides" : {
       "Data::ObjectDriver" : {
          "file" : "lib/Data/ObjectDriver.pm",
-         "version" : "0.20"
+         "version" : "0.21"
       },
       "Data::ObjectDriver::BaseObject" : {
          "file" : "lib/Data/ObjectDriver/BaseObject.pm"
@@ -96,6 +158,9 @@
       "Data::ObjectDriver::Driver::DBD" : {
          "file" : "lib/Data/ObjectDriver/Driver/DBD.pm"
       },
+      "Data::ObjectDriver::Driver::DBD::MariaDB" : {
+         "file" : "lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm"
+      },
       "Data::ObjectDriver::Driver::DBD::Oracle" : {
          "file" : "lib/Data/ObjectDriver/Driver/DBD/Oracle.pm"
       },
@@ -159,7 +224,7 @@
          "web" : "https://github.com/sixapart/data-objectdriver";
       }
    },
-   "version" : "0.20",
+   "version" : "0.21",
    "x_authority" : "cpan:SIXAPART",
    "x_contributors" : [
       "Adam Thomason <[email protected]>",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/META.yml 
new/Data-ObjectDriver-0.21/META.yml
--- old/Data-ObjectDriver-0.20/META.yml 2020-09-14 14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/META.yml 2020-10-29 06:58:38.000000000 +0100
@@ -9,7 +9,7 @@
 configure_requires:
   Module::Build::Tiny: '0.035'
 dynamic_config: 0
-generated_by: 'Minilla/v3.1.10, CPAN::Meta::Converter version 2.150010'
+generated_by: 'Minilla/v3.1.11, CPAN::Meta::Converter version 2.150010'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -25,10 +25,41 @@
     - examples
     - author
     - builder
+optional_features:
+  test_fork:
+    description: 'Test Fork'
+    requires:
+      DBI: '1.614'
+      POSIX::AtFork: '0'
+      Parallel::ForkManager: '0'
+      Scalar::Util: '0'
+      Test::SharedFork: '0'
+  test_mariadb:
+    description: 'Test MariaDB'
+    requires:
+      DBD::MariaDB: '0'
+      SQL::Translator: '0'
+      Test::mysqld: '0'
+  test_mysql:
+    description: 'Test MySQL'
+    requires:
+      DBD::mysql: '0'
+      SQL::Translator: '0'
+      Test::mysqld: '0'
+  test_postgresql:
+    description: 'Test PostgreSQL'
+    requires:
+      DBD::Pg: '0'
+      SQL::Translator: '0'
+      Test::PostgreSQL: '0'
+  test_sqlite:
+    description: 'Test SQLite'
+    requires:
+      DBD::SQLite: '0'
 provides:
   Data::ObjectDriver:
     file: lib/Data/ObjectDriver.pm
-    version: '0.20'
+    version: '0.21'
   Data::ObjectDriver::BaseObject:
     file: lib/Data/ObjectDriver/BaseObject.pm
   Data::ObjectDriver::BaseView:
@@ -45,6 +76,8 @@
     file: lib/Data/ObjectDriver/Driver/Cache/RAM.pm
   Data::ObjectDriver::Driver::DBD:
     file: lib/Data/ObjectDriver/Driver/DBD.pm
+  Data::ObjectDriver::Driver::DBD::MariaDB:
+    file: lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm
   Data::ObjectDriver::Driver::DBD::Oracle:
     file: lib/Data/ObjectDriver/Driver/DBD/Oracle.pm
   Data::ObjectDriver::Driver::DBD::Oracle::db:
@@ -92,7 +125,7 @@
   bugtracker: https://github.com/sixapart/data-objectdriver/issues
   homepage: https://github.com/sixapart/data-objectdriver
   repository: git://github.com/sixapart/data-objectdriver.git
-version: '0.20'
+version: '0.21'
 x_authority: cpan:SIXAPART
 x_contributors:
   - 'Adam Thomason <[email protected]>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/README.md 
new/Data-ObjectDriver-0.21/README.md
--- old/Data-ObjectDriver-0.20/README.md        2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/README.md        2020-10-29 06:58:38.000000000 
+0100
@@ -578,6 +578,12 @@
 
     1;
 
+# FORK SAFETY
+
+As of version 0.21, _Data::ObjectDriver_ resets internal database handles
+after _fork(2)_ is called, but only if 
[POSIX::AtFork](https://metacpan.org/pod/POSIX%3A%3AAtFork) module is installed.
+Otherwise, _Data::ObjectDriver_ is not fork-safe.
+
 # SUPPORTED DATABASES
 
 _Data::ObjectDriver_ is very modular and it's not very difficult to add new 
drivers.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/cpanfile 
new/Data-ObjectDriver-0.21/cpanfile
--- old/Data-ObjectDriver-0.20/cpanfile 2020-09-14 14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/cpanfile 2020-10-29 06:58:38.000000000 +0100
@@ -23,3 +23,33 @@
 on test => sub {
     requires 'version';
 };
+
+feature 'test_sqlite', 'Test SQLite' => sub {
+    requires 'DBD::SQLite';
+};
+
+feature 'test_mysql', 'Test MySQL' => sub {
+    requires 'DBD::mysql';
+    requires 'Test::mysqld';
+    requires 'SQL::Translator';
+};
+
+feature 'test_mariadb', 'Test MariaDB' => sub {
+    requires 'DBD::MariaDB';
+    requires 'Test::mysqld';
+    requires 'SQL::Translator';
+};
+
+feature 'test_postgresql', 'Test PostgreSQL' => sub {
+    requires 'DBD::Pg';
+    requires 'Test::PostgreSQL';
+    requires 'SQL::Translator';
+};
+
+feature 'test_fork', 'Test Fork' => sub {
+    requires 'DBI', '1.614';
+    requires 'Parallel::ForkManager';
+    requires 'POSIX::AtFork';
+    requires 'Scalar::Util';
+    requires 'Test::SharedFork';
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm 
new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm
--- old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm      
1970-01-01 01:00:00.000000000 +0100
+++ new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver/Driver/DBD/MariaDB.pm      
2020-10-29 06:58:38.000000000 +0100
@@ -0,0 +1,10 @@
+# $Id$
+
+package Data::ObjectDriver::Driver::DBD::MariaDB;
+use strict;
+use warnings;
+use base qw( Data::ObjectDriver::Driver::DBD::mysql );
+
+sub fetch_id { $_[3]->{mariadb_insertid} || $_[3]->{insertid} }
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver/Driver/DBI.pm 
new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver/Driver/DBI.pm
--- old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver/Driver/DBI.pm      
2020-09-14 14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver/Driver/DBI.pm      
2020-10-29 06:58:38.000000000 +0100
@@ -13,6 +13,16 @@
 use Data::ObjectDriver::Driver::DBD;
 use Data::ObjectDriver::Iterator;
 
+my $ForkSafe = _is_fork_safe();
+my %Handles;
+
+sub _is_fork_safe {
+    return if exists $ENV{DOD_FORK_SAFE} and !$ENV{DOD_FORK_SAFE};
+    eval { require POSIX::AtFork; 1 } or return;
+    eval { require Scalar::Util; Scalar::Util->import('weaken'); 1 } or return;
+    return 1;
+}
+
 __PACKAGE__->mk_accessors(qw( dsn username password connect_options dbh 
get_dbh dbd prefix reuse_dbh force_no_prepared_cache));
 
 
@@ -36,6 +46,17 @@
         }
         $driver->dbd(Data::ObjectDriver::Driver::DBD->new($type));
     }
+
+    if ($ForkSafe) {
+        # Purge cached handles
+        weaken(my $driver_weaken = $driver);
+        POSIX::AtFork->add_to_child(sub {
+            return unless $driver_weaken;
+            $driver_weaken->dbh(undef);
+            %Handles = ();
+        });
+    }
+
     $driver;
 }
 
@@ -61,7 +82,6 @@
     return ($driver->dbd->can_prepare_cached_statements)? 
$dbh->prepare_cached($sql) : $dbh->prepare($sql);
 }
 
-my %Handles;
 sub init_db {
     my $driver = shift;
     my $dbh;
@@ -72,6 +92,7 @@
         eval {
             $dbh = DBI->connect($driver->dsn, $driver->username, 
$driver->password,
                 { RaiseError => 1, PrintError => 0, AutoCommit => 1,
+                ( $ForkSafe ? ( AutoInactiveDestroy => 1 ) : () ),
                 %{$driver->connect_options || {}} })
                 or Carp::croak("Connection error: " . $DBI::errstr);
         };
@@ -669,7 +690,7 @@
     ## if we haven't created it ourself.
     return unless $driver->{__dbh_init_by_driver};
     if (my $dbh = $driver->dbh) {
-        $dbh->disconnect if $dbh;
+        $dbh->disconnect;
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver.pm 
new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver.pm
--- old/Data-ObjectDriver-0.20/lib/Data/ObjectDriver.pm 2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/lib/Data/ObjectDriver.pm 2020-10-29 
06:58:38.000000000 +0100
@@ -11,7 +11,7 @@
 
 __PACKAGE__->mk_accessors(qw( pk_generator txn_active ));
 
-our $VERSION = '0.20';
+our $VERSION = '0.21';
 our $DEBUG = $ENV{DOD_DEBUG} || 0;
 our $PROFILE = $ENV{DOD_PROFILE} || 0;
 our $PROFILER;
@@ -758,6 +758,12 @@
 
     1;
 
+=head1 FORK SAFETY
+
+As of version 0.21, I<Data::ObjectDriver> resets internal database handles
+after I<fork(2)> is called, but only if L<POSIX::AtFork> module is installed.
+Otherwise, I<Data::ObjectDriver> is not fork-safe.
+
 =head1 SUPPORTED DATABASES
 
 I<Data::ObjectDriver> is very modular and it's not very difficult to add new 
drivers.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/01-col-inheritance.t 
new/Data-ObjectDriver-0.21/t/01-col-inheritance.t
--- old/Data-ObjectDriver-0.20/t/01-col-inheritance.t   2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/01-col-inheritance.t   2020-10-29 
06:58:38.000000000 +0100
@@ -36,6 +36,6 @@
 ok ($wine->has_column("rating")) ;
 
 END {
-    Wine->driver->dbh->disconnect;
+    disconnect_all(qw( Wine ));
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/02-basic.t 
new/Data-ObjectDriver-0.21/t/02-basic.t
--- old/Data-ObjectDriver-0.20/t/02-basic.t     2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/02-basic.t     2020-10-29 06:58:38.000000000 
+0100
@@ -281,9 +281,7 @@
 }
 
 END {
-    for (qw/Wine Recipe/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Wine Recipe/);
     teardown_dbs(qw( global ));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/03-primary-keys.t 
new/Data-ObjectDriver-0.21/t/03-primary-keys.t
--- old/Data-ObjectDriver-0.20/t/03-primary-keys.t      2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/03-primary-keys.t      2020-10-29 
06:58:38.000000000 +0100
@@ -106,9 +106,7 @@
 }
 
 END {
-    for (qw/Wine Recipe Ingredient PkLess/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Wine Recipe Ingredient PkLess/);
     teardown_dbs(qw( global ));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/04-clone.t 
new/Data-ObjectDriver-0.21/t/04-clone.t
--- old/Data-ObjectDriver-0.20/t/04-clone.t     2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/04-clone.t     2020-10-29 06:58:38.000000000 
+0100
@@ -88,9 +88,7 @@
 }
 
 END {
-    for (qw/Wine Recipe Ingredient/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Wine Recipe Ingredient/);
     teardown_dbs(qw( global ));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/05-deflate.t 
new/Data-ObjectDriver-0.21/t/05-deflate.t
--- old/Data-ObjectDriver-0.20/t/05-deflate.t   2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/05-deflate.t   2020-10-29 06:58:38.000000000 
+0100
@@ -93,8 +93,6 @@
 ok $is->[1]->{__cached};
 
 END {
-    for (qw/Recipe Ingredient/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw( Recipe Ingredient ));
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/06-errors.t 
new/Data-ObjectDriver-0.21/t/06-errors.t
--- old/Data-ObjectDriver-0.20/t/06-errors.t    2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/06-errors.t    2020-10-29 06:58:38.000000000 
+0100
@@ -30,6 +30,6 @@
    'Failed because of a unique constraint');
 
 END {
-    ErrorTest->driver->rw_handle->disconnect;
+    disconnect_all(qw( ErrorTest ));
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/07-has-a-cached.t 
new/Data-ObjectDriver-0.21/t/07-has-a-cached.t
--- old/Data-ObjectDriver-0.20/t/07-has-a-cached.t      2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/07-has-a-cached.t      2020-10-29 
06:58:38.000000000 +0100
@@ -66,8 +66,6 @@
 is $ingredient->{__cache_recipe}, undef, "cache has effectively been 
destroyed";
 
 END {
-    for (qw/Recipe Ingredient/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Recipe Ingredient/);
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/07-has-a.t 
new/Data-ObjectDriver-0.21/t/07-has-a.t
--- old/Data-ObjectDriver-0.20/t/07-has-a.t     2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/07-has-a.t     2020-10-29 06:58:38.000000000 
+0100
@@ -65,8 +65,6 @@
 is $r->recipe_id, $recipe->recipe_id, "recipe id back using 'parent_method'";
 
 END {
-    for (qw/Recipe Ingredient/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Recipe Ingredient/);
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/09-resultset.t 
new/Data-ObjectDriver-0.21/t/09-resultset.t
--- old/Data-ObjectDriver-0.20/t/09-resultset.t 2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/09-resultset.t 2020-10-29 06:58:38.000000000 
+0100
@@ -169,8 +169,8 @@
     my $result = Wine->result({rating => { op => '<=', 'value' => 4}}, { sort 
=> 'rating', direction => 'descend' });
     $result->_load_results;
     $result->add_term({rating => { op => '<=', 'value' => 3}});
-    diag "calling next() after add_term() with 'op'" . $result->next; ## this 
should return the object which has "rating == 3".
+    note "calling next() after add_term() with 'op'" . $result->next; ## this 
should return the object which has "rating == 3".
 }
 
-$wine->driver->dbh->disconnect;
+disconnect_all($wine);
 teardown_dbs(qw( global ));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/10-resultset-peek.t 
new/Data-ObjectDriver-0.21/t/10-resultset-peek.t
--- old/Data-ObjectDriver-0.20/t/10-resultset-peek.t    2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/10-resultset-peek.t    2020-10-29 
06:58:38.000000000 +0100
@@ -146,5 +146,5 @@
 is $result->next->name, 'Stags Leap';
 ok ! $result->peek_next, "Stags Leap was the last one";
 
-$wine->driver->dbh->disconnect;
+disconnect_all($wine);
 teardown_dbs(qw( global ));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/12-windows.t 
new/Data-ObjectDriver-0.21/t/12-windows.t
--- old/Data-ObjectDriver-0.20/t/12-windows.t   2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/12-windows.t   2020-10-29 06:58:38.000000000 
+0100
@@ -97,8 +97,7 @@
 is( $load_count, 2, "2 objects loaded; limit argument respected");
 $iter->end;
 
-$r->driver->dbh->disconnect;
-$i->driver->dbh->disconnect;
+disconnect_all($r, $i);
 teardown_dbs(qw( global ));
 
 print Dumper( Data::ObjectDriver->profiler->query_log ) if $ENV{DOD_PROFILE};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/20-driver-sqlite.t 
new/Data-ObjectDriver-0.21/t/20-driver-sqlite.t
--- old/Data-ObjectDriver-0.20/t/20-driver-sqlite.t     2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/20-driver-sqlite.t     2020-10-29 
06:58:38.000000000 +0100
@@ -63,6 +63,6 @@
 is $result->rating, 3, 'Stags Leap is a 3';
 
 END {
-    Wine->driver->rw_handle->disconnect;
+    disconnect_all(qw( Wine ));
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/31-cached.t 
new/Data-ObjectDriver-0.21/t/31-cached.t
--- old/Data-ObjectDriver-0.20/t/31-cached.t    2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/31-cached.t    2020-10-29 06:58:38.000000000 
+0100
@@ -188,8 +188,6 @@
 require './t/txn-common.pl';
 
 END {
-    for (qw/Recipe Ingredient/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Recipe Ingredient/);
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/32-partitioned.t 
new/Data-ObjectDriver-0.21/t/32-partitioned.t
--- old/Data-ObjectDriver-0.20/t/32-partitioned.t       2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/32-partitioned.t       2020-10-29 
06:58:38.000000000 +0100
@@ -126,7 +126,6 @@
 require './t/txn-common.pl';
 
 END {
-    Recipe->driver->rw_handle->disconnect;
-    $_->rw_handle->disconnect for @{ Ingredient->driver->get_driver->(undef, 
{multi_partition => 1})->partitions };
+    disconnect_all(qw( Recipe Ingredient ));
     teardown_dbs(qw( global cluster1 cluster2 ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/33-views.t 
new/Data-ObjectDriver-0.21/t/33-views.t
--- old/Data-ObjectDriver-0.20/t/33-views.t     2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/33-views.t     2020-10-29 06:58:38.000000000 
+0100
@@ -54,8 +54,6 @@
 }
 
 END {
-    for (qw/Recipe Ingredient Ingredient2Recipe IngredientsWeighted/) {
-        $_->driver->rw_handle->disconnect;
-    }
+    disconnect_all(qw/Recipe Ingredient Ingredient2Recipe 
IngredientsWeighted/);
     teardown_dbs(qw( global ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/34-both.t 
new/Data-ObjectDriver-0.21/t/34-both.t
--- old/Data-ObjectDriver-0.20/t/34-both.t      2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/34-both.t      2020-10-29 06:58:38.000000000 
+0100
@@ -187,7 +187,6 @@
 require './t/txn-common.pl';
 
 END {
-    Recipe->driver->rw_handle->disconnect;
-    $_->rw_handle->disconnect for @{ Ingredient->driver->get_driver->(undef, 
{multi_partition => 1})->partitions };
+    disconnect_all(qw( Recipe Ingredient ));
     teardown_dbs(qw( global cluster1 cluster2 ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/35-multiplexed.t 
new/Data-ObjectDriver-0.21/t/35-multiplexed.t
--- old/Data-ObjectDriver-0.20/t/35-multiplexed.t       2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/35-multiplexed.t       2020-10-29 
06:58:38.000000000 +0100
@@ -139,7 +139,5 @@
     is $obj2->recipe_id, $obj->recipe_id;
 }
 
-for my $driver (@{ Ingredient2Recipe->driver->drivers }) {
-    $driver->dbh->disconnect;
-}
+disconnect_all(qw( Ingredient2Recipe ));
 teardown_dbs(qw( global1 global2 ));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/41-callbacks.t 
new/Data-ObjectDriver-0.21/t/41-callbacks.t
--- old/Data-ObjectDriver-0.20/t/41-callbacks.t 2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/41-callbacks.t 2020-10-29 06:58:38.000000000 
+0100
@@ -118,7 +118,7 @@
 
 
 END {
-    Wine->driver->rw_handle->disconnect;
+    disconnect_all(qw( Wine ));
     teardown_dbs(qw( global ));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/42-callbacks-multi-pk.t 
new/Data-ObjectDriver-0.21/t/42-callbacks-multi-pk.t
--- old/Data-ObjectDriver-0.20/t/42-callbacks-multi-pk.t        2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/42-callbacks-multi-pk.t        2020-10-29 
06:58:38.000000000 +0100
@@ -77,8 +77,7 @@
 };
 
 END {
-    Recipe->driver->rw_handle->disconnect;
-    $_->rw_handle->disconnect for @{ Ingredient->driver->get_driver->(undef, 
{multi_partition => 1})->partitions };
+    disconnect_all(qw( Recipe Ingredient ));
     teardown_dbs(qw( global cluster1 cluster2 ));
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/50-profiling.t 
new/Data-ObjectDriver-0.21/t/50-profiling.t
--- old/Data-ObjectDriver-0.20/t/50-profiling.t 2020-09-14 14:19:39.000000000 
+0200
+++ new/Data-ObjectDriver-0.21/t/50-profiling.t 2020-10-29 06:58:38.000000000 
+0100
@@ -123,7 +123,6 @@
 };
 
 END {
-    Recipe->driver->rw_handle->disconnect;
-    $_->rw_handle->disconnect for @{ Ingredient->driver->get_driver->(undef, 
{multi_partition => 1})->partitions };
+    disconnect_all(qw( Recipe Ingredient ));
     teardown_dbs(qw( global cluster1 cluster2 ));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/60-fork.t 
new/Data-ObjectDriver-0.21/t/60-fork.t
--- old/Data-ObjectDriver-0.20/t/60-fork.t      1970-01-01 01:00:00.000000000 
+0100
+++ new/Data-ObjectDriver-0.21/t/60-fork.t      2020-10-29 06:58:38.000000000 
+0100
@@ -0,0 +1,80 @@
+use strict;
+use warnings;
+use lib 't/lib';
+
+$Data::ObjectDriver::DEBUG = 0;
+use Test::More;
+use DodTestUtil;
+
+BEGIN {
+    my @requires = qw(
+        Parallel::ForkManager
+        Test::SharedFork
+    );
+
+    for my $module (@requires) {
+        eval "require $module" or plan skip_all => "requires $module";
+    }
+    DodTestUtil->check_driver;
+}
+
+setup_dbs({
+    global => [ qw( wines ) ],
+});
+
+use Wine;
+
+my $wine = Wine->new;
+$wine->name("Latour");
+ok($wine->save, 'Object saved successfully');
+
+my $wine_id = $wine->id;
+undef $wine;
+$wine = Wine->lookup($wine_id); 
+
+ok $wine;
+
+my $max = $ENV{DOD_TEST_MAX_FORK} || 10;
+my $pm = Parallel::ForkManager->new( $ENV{DOD_TEST_WORKERS} || 4 );
+$pm->run_on_finish(sub {
+    my ($pid, $exit, $ident) = @_;
+    ok !$exit, "pid $pid exits $exit";
+});
+$pm->run_on_start(sub {
+    my ($pid, $ident) = @_;
+    note "pid $pid starts";
+});
+for my $id ( 1 .. $max ) {
+    my $pid = $pm->start and next;
+    my $new_wine = Wine->new;
+    $new_wine->name("Wine $id");
+    $new_wine->begin_work;
+    ok $new_wine->save, "saved wine $id";
+    $new_wine->commit;
+
+    my ($result) = Wine->result({name => 'Latour'});
+    ok !$result->is_finished, "not yet finished";
+    ok my $latour = $result->next, "next";
+    is $latour->name => 'Latour', "found Latour";
+    ok !$result->next, "no more next";
+    ok $result->is_finished, "finished";
+
+    $pm->finish;
+}
+
+$pm->wait_all_children;
+
+pass("waited all children");
+
+my $result = Wine->result({});
+my %seen;
+while( my $wine = $result->next ) {
+    $seen{$wine->name} = 1;
+}
+
+ok $seen{Latour}, "seen Latour";
+ok $seen{"Wine $_"}, "seen Wine $_" for 1 .. $max;
+
+done_testing;
+
+teardown_dbs('global');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Data-ObjectDriver-0.20/t/lib/DodTestUtil.pm 
new/Data-ObjectDriver-0.21/t/lib/DodTestUtil.pm
--- old/Data-ObjectDriver-0.20/t/lib/DodTestUtil.pm     2020-09-14 
14:19:39.000000000 +0200
+++ new/Data-ObjectDriver-0.21/t/lib/DodTestUtil.pm     2020-10-29 
06:58:38.000000000 +0100
@@ -5,23 +5,35 @@
 use File::Spec;
 use Test::More;
 
-our @EXPORT = qw/setup_dbs teardown_dbs/;
+our @EXPORT = qw/setup_dbs teardown_dbs disconnect_all/;
 
 my %Requires = (
     SQLite     => 'DBD::SQLite',
     MySQL      => 'Test::mysqld',
+    MariaDB    => 'Test::mysqld',
     PostgreSQL => 'Test::PostgreSQL',
     Oracle     => 'DBD::Oracle',
     SQLServer  => 'DBD::ODBC',
 );
 
 my %TestDB;
+my $Driver;
 
-sub driver { $ENV{DOD_TEST_DRIVER} || 'SQLite' }
+sub driver { $Driver ||= _driver() }
+
+sub _driver {
+    my $driver = $ENV{DOD_TEST_DRIVER} || 'SQLite';
+    return $driver if exists $Requires{$driver};
+    return 'PostgreSQL' if lc $driver eq 'pg';
+    for my $key (keys %Requires) {
+        return $key if lc $key eq lc $driver;
+    }
+    plan skip_all => "Unknown driver: $driver";
+}
 
 sub check_driver {
     my $driver = driver();
-    my $module = $Requires{$driver} or plan skip_all => "Uknonwn driver: 
$driver";
+    my $module = $Requires{$driver};
     unless ( eval "require $module; 1" ) {
         plan skip_all => "Test requires $module";
     }
@@ -40,20 +52,38 @@
     $dbname . $$ . '.db';
 }
 
+my $test_mysqld_dsn;
 sub dsn {
     my($dbname) = @_;
     my $driver = driver();
     if ( my $dsn = env('DOD_TEST_DSN', $dbname) ) {
         return "$dsn;dbname=$dbname";
     }
-    if ( $driver eq 'MySQL' ) {
+    if ( $driver =~ /MySQL|MariaDB/ ) {
+        if ( $driver eq 'MariaDB' && !$test_mysqld_dsn ) {
+            my $help = `mysql --help`;
+            my ($mariadb_version) = $help =~ 
/\A.*?([0-9]+\.[0-9]+)\.[0-9]+\-MariaDB/;
+            no warnings 'redefine';
+            $test_mysqld_dsn = \&Test::mysqld::dsn;
+            *Test::mysqld::dsn = sub {
+                my $dsn = $test_mysqld_dsn->(@_);
+                # cf. https://github.com/kazuho/p5-test-mysqld/issues/32
+                $dsn =~ s/;user=root// if $mariadb_version && $mariadb_version 
> 10.3;
+                $dsn;
+            };
+        }
         $TestDB{$dbname} ||= Test::mysqld->new(
             my_cnf => {
                 'skip-networking' => '', # no TCP socket
                 'sql-mode' => 
'TRADITIONAL,NO_AUTO_VALUE_ON_ZERO,ONLY_FULL_GROUP_BY',
             }
         ) or die $Test::mysqld::errstr;
-        return $TestDB{$dbname}->dsn;
+        my $dsn = $TestDB{$dbname}->dsn;
+        if ( $driver eq 'MariaDB' ) {
+            $dsn =~ s/^dbi:mysql/dbi:MariaDB/i;
+            $dsn =~ s/mysql_/mariadb_/ig;
+        }
+        return $dsn;
     }
     if ( $driver eq 'PostgreSQL' ) {
         $TestDB{$dbname} ||= Test::PostgreSQL->new(
@@ -65,7 +95,8 @@
         return $TestDB{$dbname}->dsn;
     }
     if ( $driver eq 'SQLite' ) {
-        return 'dbi:SQLite:' . db_filename($dbname);
+        $TestDB{$dbname} ||= db_filename($dbname);
+        return 'dbi:SQLite:' . $TestDB{$dbname};
     }
 }
 
@@ -75,8 +106,8 @@
     for my $dbname (keys %$info) {
         my $dbh = DBI->connect(
             dsn($dbname),
-            env('DOD_TEST_USER', $dbname),
-            env('DOD_TEST_PASS', $dbname),
+            env('DOD_TEST_USER', $dbname) || undef,
+            env('DOD_TEST_PASS', $dbname) || undef,
             { RaiseError => 1, PrintError => 0, ShowErrorStatement => 1 });
         for my $table (@{ $info->{$dbname} }) {
             $dbh->do($_) for create_sql($table);
@@ -88,17 +119,46 @@
 sub teardown_dbs {
     my(@dbs) = @_;
     my $driver = driver();
+    return unless $driver eq 'SQLite';
     for my $db (@dbs) {
-        next unless $driver eq 'SQLite';
-        my $file = db_filename($db);
+        my $file = $TestDB{$db};
         next unless -e $file;
-        unlink $file or die "Can't teardown $db: $!";
+        unlink $file or die "Can't teardown $file: $!";
+    }
+}
+
+sub disconnect_all {
+    my @tables = @_;
+    return unless driver() eq 'SQLite';
+    for my $table (@tables) {
+        my $driver = $table->driver;
+        if ($driver->can('fallback')) {
+            $driver = $driver->fallback;
+        }
+        if ($driver->can('dbh')) {
+            my $dbh = $driver->dbh or next;
+            $dbh->disconnect;
+        }
+        elsif ($driver->can('drivers')) {
+            for my $d (@{ $driver->drivers }) {
+                my $dbh = $d->dbh or next;
+                $dbh->disconnect;
+            }
+        }
+        else {
+            my @drivers = @{ $driver->get_driver->(undef, {multi_partition => 
1})->partitions };
+            for my $d (@drivers) {
+                my $dbh = $d->dbh or next;
+                $dbh->disconnect;
+            }
+        }
     }
 }
 
 sub create_sql {
     my($table) = @_;
     my $driver = driver();
+    $driver = 'MySQL' if $driver eq 'MariaDB';
     my $file = File::Spec->catfile('t', 'schemas', $table . '.sql');
     open my $fh, $file or die "Can't open $file: $!";
     my $sql = do { local $/; <$fh> };


Reply via email to