#
#  Copyright 1014 MongoDB, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#

# PODNAME: MongoDB::Upgrading
# ABSTRACT: Deprecations and behavior changes from the v0 driver

__END__

=pod

=encoding UTF-8

=head1 NAME

MongoDB::Upgrading - Deprecations and behavior changes from the v0 driver

=head1 VERSION

version v0.999.998.3

=head1 DESCRIPTION

While the v1 driver preserves backwards compatibility in most of the API,
there are still some areas where the old API has been deprecated or changed
in a backward breaking way.

This document is intended to help developers update their code to take into
account API changes from the v0 driver to the v1 driver.

=head1 WORK-IN-PROGRESS

This document is a work in progress during the v1 development cycle.
It offers a best-efforts snapshot of changes at a point in time.

=head1 RATIONALE

While backwards-compatibility is important, changes to the driver were
sometimes deemed necessary to achieve certain goals:

=over 4

=item *

consistency – many parts of the v0 API were inconsistent, behaving differently from method to method; the v1 API minimizes developer surprises by improving consistency in return types and exception types.

=item *

simplification – many configuration settings, like write concern, were split across multiple attributes, making them hard to manage collectively or consistently as semantics changed across server versions.

=item *

encapsulation – too many low-level, internal operations were exposed as part of the API, which complicates maintenance work; the v1 API aims to minimize the "public surface" available to developers.

=item *

abstraction – many methods returned raw server documents for end-user code to inspect, which is brittle in the face of changes by the server over time; the v1 API uses objects to abstract the details behind standard method calls.

=item *

compatibility – some new features or changes in the MongoDB server, like the client authentication model, no longer fit the old driver design.

=item *

portability – the v0 driver had a large dependency tree and required a compiler and various libraries; the v1 driver shrinks the dependency tree substantially and uses widely-used CPAN modules in place of custom C code when possible.

=back

=head1 INSTALLATION AND DEPENDENCY CHANGES

=head2 SSL and SASL

The v0 driver required a compiler and OpenSSL and libgsasl for SSL and SASL
support, respectively.  The v1 driver instead relies on CPAN modules
C<IO::Socket::SSL> and C<Authen::SASL> for SSL and SASL support,
respectively.

SSL configuration is now possible via the L<ssl
attribute|MongoDB::MongoClient/ssl>.

Authentication configuration is described in L<MongoDB::MongoClient/AUTHENTICATION>.

=head1 BEHAVIOR CHANGES

=head2 MongoClient configuration immutability

Attributes are changing to be immutable to prevent global behavior changes.
(E.g. changing an attribute value in some part of the code changes it for
all parts of the code.)

As of Alpha 2, the following attributes are now immutable:

=over 4

=item *

C<ssl>

=item *

C<read_preference> – but read preference can be set at the database and collection level for localized needs.  See a subsequent section for more.

=back

Other attributes will be made immutable in subsequent alpha releases
as internal options handling is revised.

=head2 Lazy connections and reconnections on demand

The improved approach to server monitoring and selection allows all
connections to be lazy.  When the client is constructed, no connections are
made until the first network operation is needed.  At that time, the client
will scan all servers in the seed list and begin regular monitoring.
Connections that drop will be re-established when needed.

See L<SERVER SELECTION|MongoDB::MongoClient/SERVER SELECTION> and L<SERVER
MONITORING|MongoDB::MongoClient/SERVER MONITORING> in
L<MongoDB::MongoClient> for details.

=head2 Exceptions are the preferred error handling approach

In the v0 driver, errors could be indicated in various ways:

=over 4

=item *

boolean return value

=item *

string return value is an error; hash ref is success

=item *

document that might contain an 'err', 'errmsg' or '$err' field

=item *

thrown string exception

=back

Regardless of the documented error handling, every method that involved a
network operation would throw an exception on various network errors.

In the v1 driver, exceptions objects are the standard way of indicating
errors.  The exception hierarchy is described in L<MongoDB::Error>.

=head2 Cursors and query responses

In v0, L<MongoDB::Cursor> objects were used for ordinary queries as well as
the query-like commands aggregation and parallel scan.  However, only
cursor iteration commands worked for aggregation and parallel scan
"cursors"; the rest of the L<MongoDB::Cursor> API didn't apply and was
fatal.

In v1, all result iteration is done via the new L<MongoDB::QueryResult>
class.  L<MongoDB::Cursor> is now just a thin wrapper that holds query
parameters, instantiates a L<MongoDB::QueryResult> on demand, and passes
iteration methods through to the query result object.

This significantly simplifes the code base and should have little end-user
visibility unless users are specifically checking the return type of
queries and query-like methods.

The C<explain> cursor method no longer resets the cursor.

The C<slave_ok> cursor method now sets the C<read_preference>
to 'secondaryPreferred' or clears it to 'primary'.

Parallel scan "cursors" are now L<QueryResult> objects, with the same
iteration methods as in v0.

=head2 Aggregation API

On MongoDB 2.6 or later, C<aggregate> always uses a cursor to execute
the query.  The C<batchSize> option has been added (but has no effect
prior to 2.6).  The C<cursor> option is deprecated.

The return types for the C<aggregate> method are now B<always>
L<QueryResult> objects, regardless of whether the aggregation uses a cursor
internally or is an 'explain'.

B<NOTE>: To help users with a 2.6 mongos and mixed version shards with
versions before 2.6, passing the deprecated 'cursor' option with a false
value will disable the use of a cursor.  This workaround is provided for
convenience and will be removed when 2.4 is no longer supported.

=head2 Read preference objects and the C<read_preference> method

A new L<MongoDB::ReadPreference> class is used to encapsulate read
preference attributes.  In the v1 driver, it is set as an immutable
attribute on L<MongoDB::MongoClient>:

    MongoDB::MongoClient->new( ..., read_preference => { ... } );

If provided as a hash reference, it will be coerced to a
MongoDB::ReadPreference object (and validated).  You can also provide
it as a string that will be coerced to a read preference mode.

    MongoDB::MongoClient->new( ..., read_preference => 'primaryPreferred' );

The old C<read_preference> method to change the read preference has been
removed and trying to set a read preference after the client has been
created is a fatal error.

As C<read_preference> is now the name of an attribute, the return value
is the value of the attribute.

For localized changes, the C<get_database> and C<get_collection> methods
both take optional parameters that allow setting a read preference.

    my $coll = $db->get_collection(
        "foo", { read_preference => 'secondary' }
    );

For L<MongoDB::Cursor>, the C<read_preference> method sets a hidden read
preference attribute that is used for the query in place of the
L<MongoDB::MongoClient> default C<read_preference> attribute.  This means
that calling C<read_preference> on a cursor object no longer changes the
read preference globally on the client – the read preference change is
scoped to the cursor object only.

=head2 Write concern objects and removing the C<safe> option

A new L<MongoDB::WriteConcern> class is used to encapsulate write concern
attributes.  In the v1 driver, it is set as an immutable
attribute on L<MongoDB::MongoClient>:

    MongoDB::MongoClient->new( ..., write_concern => { ... } );

If provided as a hash reference, it will be coerced to a
L<MongoDB::WriteConcern> object (and validated).

It is inherited by L<MongoDB::Database>, L<MongoDB::Collection>,
and L<MongoDB::GridFS> objects unless provided as an option to
the relevant factory methods:

    $db = $client->get_database(
        "test", { write_concern => { w => 'majority' } }
    );

    $coll = $db->get_collection(
        "people", { write_concern => { w => 1 } }
    );

    $gridfs = $db->get_gridfs(
        "fs", { write_concern => { w => 0 } }
    );

The C<safe> option is no longer used in new method APIs.

=head2 Authentication

Authentication now happens automatically on connection during the
"handshake" with any given server based on the L<auth_mechanism
attribute|MongoDB::MongoClient/auth_mechanism>.

The C<authenticate> method in L<MongoDB::MongoClient> is deprecated and the
behavior has changed slightly.  When called, all connections are closed,
and the authentication configuration is reset as if the arguments had been
used in the constructor initially, and at least one connection is reopened
to ensure authentication succeeds (or else an exception is thrown).

In a future release, this method will be removed entirely and
authentication options will only be allowed as constructor arguments.

=head2 Bulk insertion

Insertion via the bulk API will insert an C<_id> into the original
document if one does not exist.  Previous documentation was not specific
whether this was the case or if the C<_id> was added to a clone.

As the regular insertion methods from L<MongoDB::Collection> modified the
original, that was adopted for the Bulk API as well.

All methods are now specifically documented as modifying the original.

=head2 Bulk write results

The bulk write results class has been renamed to
L<MongoDB::BulkWriteResult>.  It keeps C<MongoDB::WriteResult> as an empty
superclass for some backwards compatibility so that C<<
$result->isa("MongoDB::WriteResult") >> will continue to work as expected.

The attributes have been renamed to be consistent with the new CRUD API.
The legacy names are deprecated, but are available as aliases.

=head2 GridFS

The L<MongoDB::GridFS> class now has explicit read preference and write
concern attributes inherited from L<MongoDB::MongoClient> or
L<MongoDB::Database>, just like L<MongoDB::Collection>.  This means that
GridFS operations now default to an acknowledged write concern, just like
collection operations have been doing since v0.502.0 in 2012.

The use of C<safe> is deprecated.

Support for ancient, undocumented positional parameters circa 2010
has been removed.

=head2 Low-level functions removed

Low-level driver functions have been removed from the public API.

=head2 MongoDB::Collection removed

The C<MongoDB::Collection> module was deprecated in v0.502.0 and has been
removed.

=head2 C<$MongoDB::BSON::use_boolean> removed

This global variable never worked.  BSON booleans were always deserialized
as L<boolean> objects.  A future driver will add the ability to control
boolean deserialization without relying on global variables.

=head1 DEPRECATIONS

Deprecated options and methods may be removed in a future release.

=head2 Configuration options

=head3 auto_connect, auto_reconnect, find_master

These attributes no longer have any effect.  The driver always attempts to
connect or reconnect on demand and to find an appropriate server.

=head3 sasl, sasl_mechanism

There are a richer set of authentication options than these legacy options
allowed.  They are controlled through the
L<auth_mechanism|MongoDB::MongoClient/auth_mechanism> and
L<auth_mechanism_properties|MongoDB::MongoClient/auth_mechanism_properties>
attributes.  These are kept for backwards compatibility only.

=head2 Methods by module

=head3 MongoDB::MongoClient

=over 4

=item *

authenticate – Authentication parameters should now be given as client attributes.  See L<MongoDB::MongoClient/AUTHENTICATED> for more.

=item *

read_preference — Read preferences should now be given as a client attribute.  The use of the C<read_preference> method as a mutator is deprecated.

=back

=head3 MongoDB::Database

=over 4

=item *

last_error — Errors are now indicated via exceptions at the time database commands are executed.

=back

=head3 MongoDB::Collection

=over 4

=item *

insert, batch_insert, remove, update, query and find_and_modify — A new common driver CRUD API replaces these legacy methods.

=item *

get_collection — This method implied that collections could be contained inside collection.  This doesn't actually happen so it's confusing to have a Collection be a factory for collections.  Users who want nested namespaces will be explicit and create them off Database objects instead.

=back

=head1 AUTHORS

=over 4

=item *

David Golden <david@mongodb.com>

=item *

Mike Friedman <friedo@mongodb.com>

=item *

Kristina Chodorow <kristina@mongodb.com>

=item *

Florian Ragwitz <rafl@debian.org>

=back

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2015 by MongoDB, Inc..

This is free software, licensed under:

  The Apache License, Version 2.0, January 2004

=cut
