#
# * Minimum perl officially supported by DBIC is 5.8.3. This *includes* the
# basic depchain. On failure either attempt to fix it or bring it to the
-# attention of ribasushi. *DO NOT* disable 5.8 testing - it is here for a
-# reason
-#
-# * The matrix is built from two main modes - CLEANTEST = [true|false].
-# - In the first case we test with minimal deps available, and skip everything
-# listed in DBIC::OptDesps. The modules are installed with classic CPAN
-# invocations and are *fully tested*. In other words we simulate what would
-# happen if a user tried to install on a just-compiled virgin perl
-# - Without CLEANTEST we bring the armada of RDBMS and install the maximum
-# possible set of deps *without testing them*. This ensures we stay within
-# a reasonable build-time and still run as many of our tests as possible
-#
-# * The perl builds and the DBIC tests run under NUMTHREADS number of threads.
-# The testing of dependencies under CLEANTEST runs single-threaded, at least
-# until we fix our entire dep-chain to safely pass under -j
-#
-# * The way .travis.yml is fed to the command controller is idiotic - it
-# makes using multiline `bash -c` statements impossible. Therefore to
-# aid readability (our travis logic is rather complex), the bulk of
-# functionality is moved to scripts. More about the problem (and the
-# WONTFIX "explanation") here: https://github.com/travis-ci/travis-ci/issues/497
+# attention of the maintainer. *DO NOT* disable 5.8 testing - it is here for
+# a very good reason
#
+# the entire run times out after 50 minutes, or after 5 minutes without
+# console output
#
# Smoke all branches except for blocked* and wip/*
--#
--# Additionally master does not smoke with bleadperl
--# ( implemented in maint/travis-ci_scripts/10_before_install.bash )
--#
branches:
except:
- /^wip\//
email:
recipients:
- ribasushi@cpan.org
on_success: change
on_failure: always
-# FIXME - This stuff is not yet available for free OSS accounts, sadpanda
-# First paragrah on http://about.travis-ci.org/docs/user/caching/
-#cache:
-# apt: true
-# directories:
-# - /var/cache/apt/archives
+addons:
+ apt:
+ packages:
+ - libapp-nopaste-perl
+ - net-tools
+# This is probably a net-loss for setup etc - a bare 'C' will likely fare much better
language: perl
-perl:
- - "5.18"
+# Currently not trying osx: https://github.com/travis-ci/travis-ci/issues/2314
+os: linux
-env:
- - CLEANTEST=false
- - CLEANTEST=true
+# The defaults run under the more rapid container infra. The hardware is
+# actually *much* slower, but the jobs start much faster, for more info see
+# https://docs.travis-ci.com/user/ci-environment/#Virtualization-environments
+# Combined with 'fast_finish' this will result in an "uh-oh" email as early
+# as possible
+dist: precise
+sudo: false
+env: CLEANTEST=true
+
+perl:
+ - "5.8"
+ - "5.10"
+ - "5.22-extras"
matrix:
+ fast_finish: true
+
include:
- # this particular perl is quite widespread
- - perl: 5.8.8_thr_mb
+
+ # Same as the "master matrix" above, frozen under older dist/infrastructure
+ # In genereal it is strongly recommended to keep things on the older
+ # version indefinitely - there is little value in-depth smoking on
+ # more recent software stacks
+ - perl: "5.8"
+ sudo: required
+ dist: precise
env:
- - CLEANTEST=true
- - BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=5.8.8
+ - CLEANTEST=false
- # so is this one (test a sane CPAN.pm)
- - perl: 5.12.4_thr_mb
+ - perl: "5.10"
+ sudo: required
+ dist: precise
env:
- - CLEANTEST=true
- - BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=5.12.4
+ - CLEANTEST=false
- # this is the perl suse ships
- - perl: 5.10.0_thr_dbg
+ - perl: "5.22-extras"
+ sudo: required
+ dist: precise
env:
- - CLEANTEST=true
- - BREWOPTS="-DDEBUGGING -Duseithreads"
- - BREWVER=5.10.0
+ - CLEANTEST=false
- # CLEANTEST of minimum supported
- - perl: 5.8.3_nt_mb
+ # CLEANTEST of minimum supported with non-tracing poisoning, single thread (hence the sudo)
+ - perl: "5.8.3_nt_mb"
+ sudo: required
+ dist: precise
env:
+ - VCPU_USE=1
- CLEANTEST=true
+ - POISON_ENV=true
+ - DBIC_TRACE_PROFILE=console_monochrome
+ - BREWVER=5.8.3
- BREWOPTS="-Dusemorebits"
+
+ # Full Test of minimum supported without threads with plain poisoned trace
+ - perl: "5.8.3_nt"
+ sudo: required
+ dist: precise
+ # run these under legacy - great simulation of low memory env
+ group: legacy
+ env:
+ - CLEANTEST=false
+ - POISON_ENV=true
+ - DBIC_TRACE=1
- BREWVER=5.8.3
- # Full Test of minimum supported with threads
- - perl: 5.8.5_thr
+ # Full Test of minimum supported with threads with non-tracing poisoning
+ - perl: "5.8.5_thr"
+ sudo: required
+ dist: precise
+ # run these under legacy - great simulation of low memory env
+ group: legacy
env:
- CLEANTEST=false
- - BREWOPTS="-Duseithreads"
+ - POISON_ENV=true
+ - DBIC_TRACE_PROFILE=console
- BREWVER=5.8.5
+ - BREWOPTS="-Duseithreads"
+
+ # CLEANTEST of solaris-like perl with non-tracing poisoning
+ - perl: "5.8.4_nt"
+ sudo: false
+ dist: precise
+ env:
+ - CLEANTEST=true
+ - POISON_ENV=true
- DBIC_TRACE_PROFILE=console
+ - BREWVER=5.8.4
- # Full Test of minimum supported without threads
- - perl: 5.8.3_nt
+ # Full test: this particular perl is quite widespread, single thread
+ - perl: "5.8.8_thr"
+ sudo: required
+ dist: precise
env:
+ - VCPU_USE=1
- CLEANTEST=false
- - BREWOPTS=""
- - BREWVER=5.8.3
- - DBIC_TRACE_PROFILE=console_monochrome
-
- ###
- # some permutations of tracing and envvar poisoning
+ - BREWVER=5.8.8
+ - BREWOPTS="-Duseithreads"
- - perl: 5.16.2_thr_mb
+ # CLEANTEST: this is the perl suse ships, with env poisoning
+ - perl: "5.10.0_thr_dbg"
+ sudo: false
+ dist: precise
env:
- - CLEANTEST=false
+ - CLEANTEST=true
- POISON_ENV=true
- - DBIC_TRACE=1
- - DBIC_MULTICREATE_DEBUG=0
+ - BREWVER=5.10.0
+ - BREWOPTS="-DDEBUGGING -Duseithreads"
+
+ # CLEANTEST: this one is in a number of debian-based LTS (test a sane CPAN.pm, single thread)
+ - perl: "5.14.2_thr_mb"
+ sudo: required
+ dist: precise
+ env:
+ - VCPU_USE=1
+ - CLEANTEST=true
+ - BREWVER=5.14.2
- BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=5.16.2
- - perl: 5.18
+ ###
+ # some permutations of tracing and envvar poisoning
+
+ - perl: "5.12.3_thr"
+ sudo: false
+ dist: precise
env:
- - CLEANTEST=false
+ - CLEANTEST=true
- POISON_ENV=true
+ - DBIC_TRACE=1
+ - DBIC_MULTICREATE_DEBUG=1
+ - DBIC_STORAGE_RETRY_DEBUG=1
- DBIC_TRACE_PROFILE=console
+ - BREWVER=5.12.3
+ - BREWOPTS="-Duseithreads"
- - perl: 5.8
+ - perl: "5.16.3_thr_mb"
+ sudo: required
+ dist: precise
env:
- - CLEANTEST=true
+ - CLEANTEST=false
- POISON_ENV=true
- DBIC_TRACE=1
- - DBIC_TRACE_PROFILE=console
+ - BREWVER=5.16.3
+ - BREWOPTS="-Duseithreads -Dusemorebits"
- - perl: 5.18
+ - perl: "5.18-extras"
+ sudo: required
+ # explicit new infra spec preparing for a future forced upgrade
+ dist: trusty
env:
- CLEANTEST=false
- POISON_ENV=true
- DBIC_TRACE=1
- DBIC_TRACE_PROFILE=console_monochrome
- - DBIC_MULTICREATE_DEBUG=0
+ - DBICTEST_VIA_REPLICATED=0
+ - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
###
# Start of the allow_failures block
- # old threaded with blead CPAN
- - perl: devcpan_5.8.7_thr
+ # threaded oldest possible with blead CPAN
+ - perl: "devcpan_5.8.1_thr_mb"
+ sudo: false
+ dist: precise
env:
- CLEANTEST=true
- - BREWOPTS="-Duseithreads"
- - BREWVER=5.8.7
- DEVREL_DEPS=true
+ - BREWVER=5.8.1
+ - BREWOPTS="-Duseithreads -Dusemorebits"
- # 5.10.0 threaded with blead CPAN
- - perl: devcpan_5.10.0_thr_mb
+ # oldest possible with blead CPAN with poisoning and plain trace
+ - perl: "devcpan_5.8.1"
+ sudo: false
+ dist: precise
env:
- CLEANTEST=true
- - BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=5.10.0
- DEVREL_DEPS=true
+ - POISON_ENV=true
+ - DBIC_TRACE=1
+ - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
+ - BREWVER=5.8.1
+
+ # 5.8.3 with blead CPAN
+ - perl: "devcpan_5.8.3_mb"
+ sudo: required
+ # explicit new infra spec preparing for a future forced upgrade
+ dist: trusty
+ env:
+ - CLEANTEST=false
+ - DEVREL_DEPS=true
+ - BREWVER=5.8.3
+ - BREWOPTS="-Dusemorebits"
- # 5.12.2 with blead CPAN
- - perl: devcpan_5.12.2_thr
+ # 5.8.7 threaded with blead CPAN with non-tracing poisoning
+ - perl: "devcpan_5.8.7_thr"
+ sudo: false
+ dist: precise
env:
- CLEANTEST=true
+ - DEVREL_DEPS=true
+ - POISON_ENV=true
+ - BREWVER=5.8.7
- BREWOPTS="-Duseithreads"
- - BREWVER=5.12.2
+
+ # 5.8.8 threaded MB (exercises P5#72210)
+ - perl: "devcpan_5.8.8_thr_mb"
+ sudo: false
+ dist: precise
+ env:
+ - CLEANTEST=true
+ - DBICTEST_VERSION_WARNS_INDISCRIMINATELY=1
- DEVREL_DEPS=true
+ - BREWVER=5.8.8
+ - BREWOPTS="-Duseithreads -Dusemorebits"
- # recentish threaded stable with blead CPAN
- - perl: devcpan_5.18.2_thr_mb
+ # 5.10.0 threaded with blead CPAN
+ - perl: "devcpan_5.10.0_thr_mb"
+ sudo: false
+ dist: precise
env:
- - CLEANTEST=false
+ - CLEANTEST=true
+ - DEVREL_DEPS=true
+ - BREWVER=5.10.0
- BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=5.18.2
+
+ # 5.12.1 with blead CPAN
+ - perl: "devcpan_5.12.1_thr"
+ sudo: false
+ dist: precise
+ env:
+ - CLEANTEST=true
- DEVREL_DEPS=true
+ - BREWVER=5.12.1
+ - BREWOPTS="-Duseithreads"
- # bleadperl with stock CPAN, full depchain test
- - perl: bleadperl
+ # bleadperl with stock CPAN, full depchain test with non-tracing poisoning, single thread
+ - perl: "bleadperl"
+ sudo: required
+ dist: precise
env:
+ - VCPU_USE=1
- CLEANTEST=true
+ - POISON_ENV=true
- BREWVER=blead
- # bleadperl with blead CPAN
- - perl: devcpan_bleadperl_thr_mb
+ # bleadperl with blead CPAN, single thread
+ - perl: "devcpan_bleadperl_thr_mb"
+ sudo: required
+ # explicitly do not specify dist - see what the default does
env:
+ - VCPU_USE=1
- CLEANTEST=false
- - BREWOPTS="-Duseithreads -Dusemorebits"
- - BREWVER=blead
- DEVREL_DEPS=true
+ - BREWVER=blead
+ - BREWOPTS="-Duseithreads -Dusemorebits"
+ # CLEANTEST of http://schplog.schmorp.de/2015-06-06-a-stable-perl.html with non-tracing poisoning
+ - perl: "schmorp_stableperl_thr_mb"
+ sudo: false
+ dist: precise
+ env:
+ - CLEANTEST=true
+ - POISON_ENV=true
+ - BREWVER=schmorp_stableperl
+ - BREWOPTS="-Duseithreads -Dusemorebits"
# which ones of the above can fail
allow_failures:
# these run with various dev snapshots - allowed to fail
+ - perl: devcpan_5.8.1_thr_mb
+ - perl: devcpan_5.8.1
+ - perl: devcpan_5.8.3_mb
- perl: devcpan_5.8.7_thr
+ - perl: devcpan_5.8.8_thr_mb
- perl: devcpan_5.10.0_thr_mb
- - perl: devcpan_5.12.2_thr
- - perl: devcpan_5.18.2_thr_mb
+ - perl: devcpan_5.12.1_thr
- perl: bleadperl
- perl: devcpan_bleadperl_thr_mb
+ - perl: schmorp_stableperl_thr_mb
-# sourcing the files is *EXTREMELY* important - otherwise
-# no envvars will survive
-
-# the entire run times out after 50 minutes, or after 5 minutes without
-# console output
+###
+### For the following two phases -e is *set*
+###
before_install:
+ # common functions for all run phases below
+ #
+ # this is an exporter - sourcing it is crucial
+ # among other things it also sets -e
+ #
+ - source maint/travis-ci_scripts/common.bash
+
# Sets global envvars, downloads/configures debs based on CLEANTEST
# Sets extra DBICTEST_* envvars
#
+ # this is an exporter - sourcing it is crucial
+ #
- source maint/travis-ci_scripts/10_before_install.bash
install:
# Build and switch to a custom perl if requested
# Configure the perl env, preinstall some generic toolchain parts
+ # Possibly poison the environment
+ #
+ # this is an exporter - sourcing it is crucial
#
- source maint/travis-ci_scripts/20_install.bash
+###
+### From this point on -e is *unset*, rely on travis' error handling
+###
+ - set +e
+
before_script:
# Preinstall/install deps based on envvars/CLEANTEST
#
- - source maint/travis-ci_scripts/30_before_script.bash
+ # need to invoke the after_failure script manually
+ # because 'after_failure' runs only after 'script' fails
+ #
+ - maint/getstatus maint/travis-ci_scripts/30_before_script.bash
script:
# Run actual tests
#
- - source maint/travis-ci_scripts/40_script.bash
+ - maint/getstatus maint/travis-ci_scripts/40_script.bash
+
+###
+### Set -e back, work around https://github.com/travis-ci/travis-ci/issues/3533
+###
+ - set -e
after_success:
# Check if we can assemble a dist properly if not in CLEANTEST
#
- - source maint/travis-ci_scripts/50_after_success.bash
+ - maint/getstatus maint/travis-ci_scripts/50_after_success.bash
after_failure:
- # No tasks yet
+ # Final sysinfo printout on fail
#
- #- source maint/travis-ci_scripts/50_after_failure.bash
+ - maint/getstatus maint/travis-ci_scripts/50_after_failure.bash
after_script:
# No tasks yet
#
- #- source maint/travis-ci_scripts/60_after_script.bash
-
- # if we do not unset this before we terminate the travis teardown will
- # mark the entire job as failed
- - set +e
+ #- maint/getstatus maint/travis-ci_scripts/60_after_script.bash
# $VERSION declaration must stay up here, ahead of any other package
# declarations, as to not confuse various modules attempting to determine
# this ones version, whether that be s.c.o. or Module::Metadata, etc
-$VERSION = '0.08270';
+$VERSION = '0.082899_15';
$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
use DBIx::Class::Exception;
__PACKAGE__->mk_group_accessors(inherited => '_skip_namespace_frames');
-__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve');
+__PACKAGE__->_skip_namespace_frames('^DBIx::Class|^SQL::Abstract|^Try::Tiny|^Class::Accessor::Grouped|^Context::Preserve|^Moose::Meta::');
+
+# FIXME - this is not really necessary, and is in
+# fact going to slow things down a bit
+# However it is the right thing to do in order to get
+# various install bases to highlight their brokenness
+# Remove at some unknown point in the future
+#
+# The oddball BEGIN is there for... reason unknown
+# It does make non-segfaulty difference on pre-5.8.5 perls, so shrug
+BEGIN {
+ sub DESTROY { &DBIx::Class::_Util::detected_reinvoked_destructor };
+}
sub mk_classdata {
shift->mk_classaccessor(@_);
};
}
+# *DO NOT* change this URL nor the identically named =head1 below
+# it is linked throughout the ecosystem
+sub DBIx::Class::_ENV_::HELP_URL () {
+ 'http://p3rl.org/DBIx::Class#GETTING_HELP/SUPPORT'
+}
+
1;
__END__
-=encoding UTF-8
-
=head1 NAME
DBIx::Class - Extensible and flexible object <-> relational mapper.
recommended to read (at the very least) the
L<Manuals|DBIx::Class::Manual::DocMap/Manuals> in the order presented there.
-=head1 HOW TO GET HELP
+=cut
+
+=head1 GETTING HELP/SUPPORT
-Due to the complexity of its problem domain, DBIx::Class is a relatively
+Due to the sheer size of its problem domain, DBIx::Class is a relatively
complex framework. After you start using DBIx::Class questions will inevitably
arise. If you are stuck with a problem or have doubts about a particular
-approach do not hesitate to contact the community with your questions. The
-list below is sorted by "fastest response time":
+approach do not hesitate to contact us via any of the following options (the
+list is sorted by "fastest response time"):
=over
my $cd = $millennium_cds_rs->next; # SELECT ... FROM cds JOIN artists ...
my $cd_artist_name = $cd->artist->name; # Already has the data so no 2nd query
- # new() makes a Result object but doesnt insert it into the DB.
+ # new() makes a Result object but doesn't insert it into the DB.
# create() is the same as new() then insert().
my $new_cd = $schema->resultset('CD')->new({ title => 'Spoon' });
$new_cd->artist($cd->artist);
welcome documentation improvements). The delivery methods include git-
or unified-diff formatted patches, GitHub pull requests, or plain bug
reports either via RT or the Mailing list. Contributors are generally
-granted full access to the official repository after their first patch
-passes successful review.
+granted access to the official repository after their first several
+patches pass successful review. Don't hesitate to
+L<contact|/GETTING HELP/SUPPORT> either of the L</CAT HERDERS> with
+any further questions you may have.
=for comment
FIXME: Getty, frew and jnap need to get off their asses and finish the contrib section so we can link it here ;)
=item * Travis-CI log: L<https://travis-ci.org/dbsrgits/dbix-class/builds>
=for html
--↪ Stable branch CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
++↪ Bleeding edge dev CI status: <img src="https://secure.travis-ci.org/dbsrgits/dbix-class.png?branch=master"></img>
=back
-=head1 AUTHOR
-
-mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
-
-(I mostly consider myself "project founder" these days but the AUTHOR heading
-is traditional :)
-
-=head1 CONTRIBUTORS
-
-abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
-
-acca: Alexander Kuznetsov <acca@cpan.org>
-
-aherzog: Adam Herzog <adam@herzogdesigns.com>
-
-Alexander Keusch <cpan@keusch.at>
-
-alexrj: Alessandro Ranellucci <aar@cpan.org>
-
-alnewkirk: Al Newkirk <we@ana.im>
-
-amiri: Amiri Barksdale <amiri@metalabel.com>
-
-amoore: Andrew Moore <amoore@cpan.org>
-
-andrewalker: Andre Walker <andre@andrewalker.net>
-
-andyg: Andy Grundman <andy@hybridized.org>
-
-ank: Andres Kievsky
-
-arc: Aaron Crane <arc@cpan.org>
-
-arcanez: Justin Hunter <justin.d.hunter@gmail.com>
-
-ash: Ash Berlin <ash@cpan.org>
-
-bert: Norbert Csongrádi <bert@cpan.org>
-
-blblack: Brandon L. Black <blblack@gmail.com>
-
-bluefeet: Aran Deltac <bluefeet@cpan.org>
-
-bphillips: Brian Phillips <bphillips@cpan.org>
-
-boghead: Bryan Beeley <cpan@beeley.org>
-
-brd: Brad Davis <brd@FreeBSD.org>
-
-bricas: Brian Cassidy <bricas@cpan.org>
-
-brunov: Bruno Vecchi <vecchi.b@gmail.com>
-
-caelum: Rafael Kitover <rkitover@cpan.org>
-
-caldrin: Maik Hentsche <maik.hentsche@amd.com>
-
-castaway: Jess Robinson
-
-claco: Christopher H. Laco
-
-clkao: CL Kao
-
-da5id: David Jack Olrik <djo@cpan.org>
-
-dariusj: Darius Jokilehto <dariusjokilehto@yahoo.co.uk>
-
-davewood: David Schmidt <davewood@gmx.at>
-
-daxim: Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯 <daxim@cpan.org>
-
-debolaz: Anders Nor Berle <berle@cpan.org>
-
-dew: Dan Thomas <dan@godders.org>
-
-dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
-
-dnm: Justin Wheeler <jwheeler@datademons.com>
-
-dpetrov: Dimitar Petrov <mitakaa@gmail.com>
-
-dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
-
-dyfrgi: Michael Leuchtenburg <michael@slashhome.org>
-
-edenc: Eden Cardim <edencardim@gmail.com>
-
-ether: Karen Etheridge <ether@cpan.org>
-
-felliott: Fitz Elliott <fitz.elliott@gmail.com>
-
-freetime: Bill Moseley <moseley@hank.org>
-
-frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
-
-goraxe: Gordon Irving <goraxe@cpan.org>
-
-gphat: Cory G Watson <gphat@cpan.org>
-
-Grant Street Group L<http://www.grantstreet.com/>
-
-groditi: Guillermo Roditi <groditi@cpan.org>
-
-Haarg: Graham Knop <haarg@haarg.org>
-
-hobbs: Andrew Rodland <arodland@cpan.org>
-
-ilmari: Dagfinn Ilmari MannsE<aring>ker <ilmari@ilmari.org>
-
-initself: Mike Baas <mike@initselftech.com>
-
-ironcamel: Naveed Massjouni <naveedm9@gmail.com>
-
-jawnsy: Jonathan Yu <jawnsy@cpan.org>
-
-jasonmay: Jason May <jason.a.may@gmail.com>
-
-jesper: Jesper Krogh
-
-jgoulah: John Goulah <jgoulah@cpan.org>
-
-jguenther: Justin Guenther <jguenther@cpan.org>
+=head1 AUTHORS
-jhannah: Jay Hannah <jay@jays.net>
+Even though a large portion of the source I<appears> to be written by just a
+handful of people, this library continues to remain a collaborative effort -
+perhaps one of the most successful such projects on L<CPAN|http://cpan.org>.
+It is important to remember that ideas do not always result in a direct code
+contribution, but deserve acknowledgement just the same. Time and time again
+the seemingly most insignificant questions and suggestions have been shown
+to catalyze monumental improvements in consistency, accuracy and performance.
-jmac: Jason McIntosh <jmac@appleseed-sc.com>
+=for comment this line is replaced with the author list at dist-building time
-jnapiorkowski: John Napiorkowski <jjn1056@yahoo.com>
+The canonical source of authors and their details is the F<AUTHORS> file at
+the root of this distribution (or repository). The canonical source of
+per-line authorship is the L<git repository|/HOW TO CONTRIBUTE> history
+itself.
-jon: Jon Schutz <jjschutz@cpan.org>
+=head1 CAT HERDERS
-jshirley: J. Shirley <jshirley@gmail.com>
+The fine folks nudging the project in a particular direction:
-kaare: Kaare Rasmussen
-
-konobi: Scott McWhirter
-
-littlesavage: Alexey Illarionov <littlesavage@orionet.ru>
-
-lukes: Luke Saunders <luke.saunders@gmail.com>
-
-marcus: Marcus Ramberg <mramberg@cpan.org>
-
-mattlaw: Matt Lawrence
-
-mattp: Matt Phillips <mattp@cpan.org>
-
-michaelr: Michael Reddick <michael.reddick@gmail.com>
-
-milki: Jonathan Chu <milki@rescomp.berkeley.edu>
-
-mithaldu: Christian Walde <walde.christian@gmail.com>
-
-mjemmeson: Michael Jemmeson <michael.jemmeson@gmail.com>
-
-mstratman: Mark A. Stratman <stratman@gmail.com>
-
-ned: Neil de Carteret
-
-nigel: Nigel Metheringham <nigelm@cpan.org>
-
-ningu: David Kamholz <dkamholz@cpan.org>
-
-Nniuq: Ron "Quinn" Straight" <quinnfazigu@gmail.org>
-
-norbi: Norbert Buchmuller <norbi@nix.hu>
-
-nuba: Nuba Princigalli <nuba@cpan.org>
-
-Numa: Dan Sully <daniel@cpan.org>
-
-ovid: Curtis "Ovid" Poe <ovid@cpan.org>
-
-oyse: E<Oslash>ystein Torget <oystein.torget@dnv.com>
-
-paulm: Paul Makepeace
-
-penguin: K J Cheetham
-
-perigrin: Chris Prather <chris@prather.org>
-
-peter: Peter Collingbourne <peter@pcc.me.uk>
-
-Peter Siklósi <einon@einon.hu>
-
-Peter Valdemar ME<oslash>rch <peter@morch.com>
-
-phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
-
-plu: Johannes Plunien <plu@cpan.org>
-
-Possum: Daniel LeWarne <possum@cpan.org>
-
-quicksilver: Jules Bean
-
-rafl: Florian Ragwitz <rafl@debian.org>
-
-rainboxx: Matthias Dietrich <perl@rb.ly>
-
-rbo: Robert Bohne <rbo@cpan.org>
-
-rbuels: Robert Buels <rmb32@cornell.edu>
-
-rdj: Ryan D Johnson <ryan@innerfence.com>
-
-ribasushi: Peter Rabbitson <ribasushi@cpan.org>
-
-rjbs: Ricardo Signes <rjbs@cpan.org>
-
-robkinyon: Rob Kinyon <rkinyon@cpan.org>
-
-Robert Olson <bob@rdolson.org>
-
-moltar: Roman Filippov <romanf@cpan.org>
-
-Sadrak: Felix Antonius Wilhelm Ostmann <sadrak@cpan.org>
-
-sc_: Just Another Perl Hacker
-
-scotty: Scotty Allen <scotty@scottyallen.com>
-
-semifor: Marc Mims <marc@questright.com>
-
-SineSwiper: Brendan Byrd <bbyrd@cpan.org>
-
-solomon: Jared Johnson <jaredj@nmgi.com>
-
-spb: Stephen Bennett <stephen@freenode.net>
-
-Squeeks <squeek@cpan.org>
-
-sszabo: Stephan Szabo <sszabo@bigpanda.com>
-
-talexb: Alex Beamish <talexb@gmail.com>
-
-tamias: Ronald J Kimball <rjk@tamias.net>
-
-teejay : Aaron Trevena <teejay@cpan.org>
-
-Todd Lipcon
-
-Tom Hukins
-
-tonvoon: Ton Voon <tonvoon@cpan.org>
-
-triode: Pete Gamache <gamache@cpan.org>
-
-typester: Daisuke Murase <typester@cpan.org>
-
-victori: Victor Igumnov <victori@cpan.org>
-
-wdh: Will Hawes
-
-wesm: Wes Malone <wes@mitsi.com>
-
-willert: Sebastian Willert <willert@cpan.org>
-
-wreis: Wallace Reis <wreis@cpan.org>
-
-xenoterracide: Caleb Cushing <xenoterracide@gmail.com>
+=over
-yrlnry: Mark Jason Dominus <mjd@plover.com>
+B<ribasushi>: Peter Rabbitson <ribasushi@cpan.org>
+(present day maintenance and controlled evolution)
-zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
+B<castaway>: Jess Robinson <castaway@desert-island.me.uk>
+(lions share of the reference documentation and manuals)
-Zefram: Andrew Main <zefram@fysh.org>
+B<mst>: Matt S Trout <mst@shadowcat.co.uk> (project founder -
+original idea, architecture and implementation)
-=head1 COPYRIGHT
+=back
-Copyright (c) 2005 - 2011 the DBIx::Class L</AUTHOR> and L</CONTRIBUTORS>
-as listed above.
+=head1 COPYRIGHT AND LICENSE
-=head1 LICENSE
+Copyright (c) 2005 by mst, castaway, ribasushi, and other DBIx::Class
+L</AUTHORS> as listed above and in F<AUTHORS>.
This library is free software and may be distributed under the same terms
-as perl itself.
+as perl5 itself. See F<LICENSE> for the complete licensing terms.
=head1 DESCRIPTION
-This module is a subclass of L<SQL::Abstract> and includes a number of
-DBIC-specific workarounds, not yet suitable for inclusion into the
+This module is currently a subclass of L<SQL::Abstract> and includes a number of
+DBIC-specific extensions/workarounds, not suitable for inclusion into the
L<SQL::Abstract> core. It also provides all (and more than) the functionality
of L<SQL::Abstract::Limit>, see L<DBIx::Class::SQLMaker::LimitDialects> for
more info.
-Currently the enhancements to L<SQL::Abstract> are:
+Currently the enhancements over L<SQL::Abstract> are:
=over
=item * C<GROUP BY>/C<HAVING> support (via extensions to the order_by parameter)
+=item * A rudimentary multicolumn IN operator
+
=item * Support of C<...FOR UPDATE> type of select statement modifiers
=back
+=head1 ROADMAP
+
+Some maintainer musings on the current state of SQL generation within DBIC as
+of Oct 2015
+
+=head2 Folding of most (or all) of L<SQL::Abstract (SQLA)|SQL::Abstract> into DBIC
+
+The rise of complex prefetch use, and the general streamlining of result
+parsing within DBIC ended up pushing the actual SQL generation to the forefront
+of many casual performance profiles. While the idea behind SQLA's API is sound,
+the actual implementation is terribly inefficient (once again bumping into the
+ridiculously high overhead of perl function calls).
+
+Given that SQLA has a B<very> distinct life on its own, and is used within an
+order of magnitude more projects compared to DBIC, it is prudent to B<not>
+disturb the current call chains within SQLA itself. Instead in the near future
+an effort will be undertaken to seek a more thorough decoupling of DBIC SQL
+generation from reliance on SQLA, possibly to a point where B<DBIC will no
+longer depend on SQLA> at all.
+
+B<The L<SQL::Abstract> library itself will continue being maintained> although
+it is not likely to gain many extra features, notably dialect support, at least
+not within the base C<SQL::Abstract> namespace.
+
+This work (if undertaken) will take into consideration the following
+constraints:
+
+=over
+
+=item Main API compatibility
+
+The object returned by C<< $schema->storage->sqlmaker >> needs to be able to
+satisfy most of the basic tests found in the current-at-the-time SQLA dist.
+While things like L<case|SQL::Abstract/case> or L<logic|SQL::Abstract/logic>
+or even worse L<convert|SQL::Abstract/convert> will definitely remain
+unsupported, the rest of the tests should pass (within reason).
+
+=item Ability to plug back an SQL::Abstract (or derivative)
+
+During the initial work on L<Data::Query> the test suite of DBIC turned out to
+be an invaluable asset to iron out hard-to-reason-about corner cases. In
+addition the test suite is much more vast and intricate than the tests of SQLA
+itself. This state of affairs is way too valuable to sacrifice in order to gain
+faster SQL generation. Thus a compile-time-ENV-check will be introduced along
+with an extra CI configuration to ensure that DBIC is used with an off-the-CPAN
+SQLA and that it continues to flawlessly run its entire test suite. While this
+will undoubtedly complicate the implementation of the better performing SQL
+generator, it will preserve both the usability of the test suite for external
+projects and will keep L<SQL::Abstract> from regressions in the future.
+
+=back
+
+Aside from these constraints it is becoming more and more practical to simply
+stop using SQLA in day-to-day production deployments of DBIC. The flexibility
+of the internals is simply not worth the performance cost.
+
+=head2 Relationship to L<Data::Query (DQ)|Data::Query>
+
+When initial work on DQ was taking place, the tools in L<::Storage::DBIHacks
- |http://github.com/dbsrgits/dbix-class/blob/current/blead/lib/DBIx/Class/Storage/DBIHacks.pm>
++|http://github.com/dbsrgits/dbix-class/blob/master/lib/DBIx/Class/Storage/DBIHacks.pm>
+were only beginning to take shape, and it wasn't clear how important they will
+become further down the road. In fact the I<regexing all over the place> was
+considered an ugly stop-gap, and even a couple of highly entertaining talks
+were given to that effect. As the use-cases of DBIC were progressing, and
+evidence for the importance of supporting arbitrary SQL was mounting, it became
+clearer that DBIC itself would not really benefit in any way from an
+integration with DQ, but on the contrary is likely to lose functionality while
+the corners of the brand new DQ codebase are sanded off.
+
+The current status of DBIC/DQ integration is that the only benefit is for DQ by
+having access to the very extensive "early adopter" test suite, in the same
+manner as early DBIC benefitted tremendously from usurping the Class::DBI test
+suite. As far as the DBIC user-base - there are no immediate practical upsides
+to DQ integration, neither in terms of API nor in performance.
+
+So (as described higher up) the DBIC development effort will in the foreseable
+future ignore the existence of DQ, and will continue optimizing the preexisting
+SQLA-based solution, potentially "organically growing" its own compatible
+implementation. Also (again, as described higher up) the ability to plug a
+separate SQLA-compatible class providing the necessary surface API will remain
+possible, and will be protected at all costs in order to continue providing DQ
+access to the test cases of DBIC.
+
+In the short term, after one more pass over the ResultSet internals is
+undertaken I<real soon now (tm)>, and before the SQLA/SQLMaker integration
+takes place, the preexisting DQ-based branches will be pulled/modified/rebased
+to get up-to-date with the current state of the codebase, which changed very
+substantially since the last migration effort, especially in the SQL
+classification meta-parsing codepath.
+
=cut
use base qw/
__PACKAGE__->mk_group_accessors (simple => qw/quote_char name_sep limit_dialect/);
+sub _quoting_enabled {
+ ( defined $_[0]->{quote_char} and length $_[0]->{quote_char} ) ? 1 : 0
+}
+
# for when I need a normalized l/r pair
sub _quote_chars {
+
+ # in case we are called in the old !!$sm->_quote_chars fashion
+ return () if !wantarray and ( ! defined $_[0]->{quote_char} or ! length $_[0]->{quote_char} );
+
map
{ defined $_ ? $_ : '' }
( ref $_[0]->{quote_char} ? (@{$_[0]->{quote_char}}) : ( ($_[0]->{quote_char}) x 2 ) )
my ($self, $table, $fields, $where, $rs_attrs, $limit, $offset) = @_;
- $fields = $self->_recurse_fields($fields);
+ ($fields, @{$self->{select_bind}}) = $self->_recurse_fields($fields);
if (defined $offset) {
$self->throw_exception('A supplied offset must be a non-negative integer')
- if ( $offset =~ /\D/ or $offset < 0 );
+ if ( $offset =~ /[^0-9]/ or $offset < 0 );
}
$offset ||= 0;
if (defined $limit) {
$self->throw_exception('A supplied limit must be a positive integer')
- if ( $limit =~ /\D/ or $limit <= 0 );
+ if ( $limit =~ /[^0-9]/ or $limit <= 0 );
}
elsif ($offset) {
$limit = $self->__max_int;
if( $limiter = $self->can ('emulate_limit') ) {
carp_unique(
'Support for the legacy emulate_limit() mechanism inherited from '
- . 'SQL::Abstract::Limit has been deprecated, and will be removed when '
- . 'DBIC transitions to Data::Query. If your code uses this type of '
+ . 'SQL::Abstract::Limit has been deprecated, and will be removed at '
+ . 'some future point, as it gets in the way of architectural and/or '
+ . 'performance advances within DBIC. If your code uses this type of '
. 'limit specification please file an RT and provide the source of '
. 'your emulate_limit() implementation, so an acceptable upgrade-path '
. 'can be devised'
# optimized due to hotttnesss
# my ($self, $table, $data, $options) = @_;
- # SQLA will emit INSERT INTO $table ( ) VALUES ( )
+ # FIXME SQLA will emit INSERT INTO $table ( ) VALUES ( )
# which is sadly understood only by MySQL. Change default behavior here,
- # until SQLA2 comes with proper dialect support
+ # until we fold the extra pieces into SQLMaker properly
if (! $_[2] or (ref $_[2] eq 'HASH' and !keys %{$_[2]} ) ) {
my @bind;
my $sql = sprintf(
return $$fields if $ref eq 'SCALAR';
if ($ref eq 'ARRAY') {
- return join(', ', map { $self->_recurse_fields($_) } @$fields);
+ my (@select, @bind);
+ for my $field (@$fields) {
+ my ($select, @new_bind) = $self->_recurse_fields($field);
+ push @select, $select;
+ push @bind, @new_bind;
+ }
+ return (join(', ', @select), @bind);
}
elsif ($ref eq 'HASH') {
my %hash = %$fields; # shallow copy
my $as = delete $hash{-as}; # if supplied
- my ($func, $args, @toomany) = %hash;
+ my ($func, $rhs, @toomany) = %hash;
# there should be only one pair
if (@toomany) {
$self->throw_exception( "Malformed select argument - too many keys in hash: " . join (',', keys %$fields ) );
}
- if (lc ($func) eq 'distinct' && ref $args eq 'ARRAY' && @$args > 1) {
+ if (lc ($func) eq 'distinct' && ref $rhs eq 'ARRAY' && @$rhs > 1) {
$self->throw_exception (
'The select => { distinct => ... } syntax is not supported for multiple columns.'
- .' Instead please use { group_by => [ qw/' . (join ' ', @$args) . '/ ] }'
- .' or { select => [ qw/' . (join ' ', @$args) . '/ ], distinct => 1 }'
+ .' Instead please use { group_by => [ qw/' . (join ' ', @$rhs) . '/ ] }'
+ .' or { select => [ qw/' . (join ' ', @$rhs) . '/ ], distinct => 1 }'
);
}
+ my ($rhs_sql, @rhs_bind) = $self->_recurse_fields($rhs);
my $select = sprintf ('%s( %s )%s',
$self->_sqlcase($func),
- $self->_recurse_fields($args),
+ $rhs_sql,
$as
? sprintf (' %s %s', $self->_sqlcase('as'), $self->_quote ($as) )
: ''
);
- return $select;
+ return ($select, @rhs_bind);
}
- # Is the second check absolutely necessary?
elsif ( $ref eq 'REF' and ref($$fields) eq 'ARRAY' ) {
- push @{$self->{select_bind}}, @{$$fields}[1..$#$$fields];
- return $$fields->[0];
+ return @{$$fields};
}
else {
$self->throw_exception( $ref . qq{ unexpected in _recurse_fields()} );
# things in the SQLA space need to have more info about the $rs they
# create SQL for. The alternative would be to keep expanding the
# signature of _select with more and more positional parameters, which
-# is just gross. All hail SQLA2!
+# is just gross.
+#
+# FIXME - this will have to transition out to a subclass when the effort
+# of folding the SQLA machinery into SQLMaker takes place
sub _parse_rs_attrs {
my ($self, $arg) = @_;
my $sql = '';
+ my @sqlbind;
- if ($arg->{group_by}) {
- # horrible horrible, waiting for refactor
- local $self->{select_bind};
- if (my $g = $self->_recurse_fields($arg->{group_by}) ) {
- $sql .= $self->_sqlcase(' group by ') . $g;
- push @{$self->{group_bind} ||= []}, @{$self->{select_bind}||[]};
- }
+ if (
+ $arg->{group_by}
+ and
+ @sqlbind = $self->_recurse_fields($arg->{group_by})
+ ) {
+ $sql .= $self->_sqlcase(' group by ') . shift @sqlbind;
+ push @{$self->{group_bind}}, @sqlbind;
}
- if (defined $arg->{having}) {
- my ($frag, @bind) = $self->_recurse_where($arg->{having});
- push(@{$self->{having_bind}}, @bind);
- $sql .= $self->_sqlcase(' having ') . $frag;
+ if (
+ $arg->{having}
+ and
+ @sqlbind = $self->_recurse_where($arg->{having})
+ ) {
+ $sql .= $self->_sqlcase(' having ') . shift @sqlbind;
+ push(@{$self->{having_bind}}, @sqlbind);
}
- if (defined $arg->{order_by}) {
+ if ($arg->{order_by}) {
+ # unlike the 2 above, _order_by injects into @{...bind...} for us
$sql .= $self->_order_by ($arg->{order_by});
}
my ($self, $arg) = @_;
# check that we are not called in legacy mode (order_by as 4th argument)
- if (ref $arg eq 'HASH' and not grep { $_ =~ /^-(?:desc|asc)/i } keys %$arg ) {
- return $self->_parse_rs_attrs ($arg);
- }
- else {
- my ($sql, @bind) = $self->next::method($arg);
- push @{$self->{order_bind}}, @bind;
- return $sql;
- }
+ (
+ ref $arg eq 'HASH'
+ and
+ not grep { $_ =~ /^-(?:desc|asc)/i } keys %$arg
+ )
+ ? $self->_parse_rs_attrs ($arg)
+ : do {
+ my ($sql, @bind) = $self->next::method($arg);
+ push @{$self->{order_bind}}, @bind;
+ $sql; # RV
+ }
+ ;
}
sub _split_order_chunk {
# Backcompat for the old days when a plain hashref
# { 't1.col1' => 't2.col2' } meant ON t1.col1 = t2.col2
- # Once things settle we should start warning here so that
- # folks unroll their hacks
if (
ref $cond eq 'HASH'
and
and
! ref ( (values %$cond)[0] )
) {
+ carp_unique(
+ "ResultSet {from} structures with conditions not conforming to the "
+ . "SQL::Abstract syntax are deprecated: you either need to stop abusing "
+ . "{from} altogether, or express the condition properly using the "
+ . "{ -ident => ... } operator"
+ );
$cond = { keys %$cond => { -ident => values %$cond } }
}
elsif ( ref $cond eq 'ARRAY' ) {
return $self->_recurse_where($cond);
}
-# This is hideously ugly, but SQLA does not understand multicol IN expressions
-# FIXME TEMPORARY - DQ should have native syntax for this
-# moved here to raise API questions
+# !!! EXPERIMENTAL API !!! WILL CHANGE !!!
+#
+# This is rather odd, but vanilla SQLA does not have support for multicolumn IN
+# expressions
+# Currently has only one callsite in ResultSet, body moved into this subclass
+# of SQLA to raise API questions like:
+# - how do we convey a list of idents...?
+# - can binds reside on lhs?
#
# !!! EXPERIMENTAL API !!! WILL CHANGE !!!
sub _where_op_multicolumn_in {
\[ join( ' IN ', shift @$$lhs, shift @$$rhs ), @$$lhs, @$$rhs ];
}
-1;
-
-=head1 AUTHORS
+=head1 FURTHER QUESTIONS?
-See L<DBIx::Class/CONTRIBUTORS>.
+Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
-=head1 LICENSE
+=head1 COPYRIGHT AND LICENSE
-You may distribute this code under the same terms as Perl itself.
+This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
+by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
+redistribute it and/or modify it under the same terms as the
+L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
=cut
+
+1;