—#
# Copyright 2009-2013 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
#
#
# 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.
#
package
MongoDB::BSON;
# ABSTRACT: Tools for serializing and deserializing data in BSON form
use
version;
our
$VERSION
=
'v0.999.999.2'
;
# TRIAL
use
XSLoader;
XSLoader::load(
"MongoDB"
,
$VERSION
);
use
Carp ();
use
Config;
use
if
!
$Config
{use64bitint},
"Math::BigInt"
;
use
MongoDB::Error;
use
Moose;
use
MongoDB::_Types -types;
use
Types::Standard -types;
#pod =attr dbref_callback
#pod
#pod A document with keys C<$ref> and C<$id> is a special MongoDB convention
#pod representing a
#pod
#pod This attribute specifies a function reference that will be called with a hash
#pod reference argument representing a DBRef.
#pod
#pod The hash reference will have keys C<$ref> and C<$id> and may have C<$db> and
#pod other keys. The callback must return a scalar value representing the dbref
#pod (e.g. a document, an object, etc.)
#pod
#pod The default returns the DBRef hash reference without modification.
#pod
#pod =cut
has
dbref_callback
=> (
is
=>
'ro'
,
isa
=> CodeRef,
default
=>
sub
{
sub
{
shift
} },
);
#pod =attr dt_type
#pod
#pod Sets the type of object which is returned for BSON DateTime fields. The default
#pod is L<DateTime>. Other acceptable values are L<Time::Moment>, L<DateTime::Tiny>
#pod and C<undef>. The latter will give you the raw epoch value rather than an
#pod object.
#pod
#pod # XXX add MongoDB::BSON::DateTime support and make it the default
#pod
#pod =cut
has
dt_type
=> (
is
=>
'ro'
,
isa
=> Str|Undef,
default
=>
'DateTime'
,
);
#pod =attr error_callback
#pod
#pod This attribute specifies a function reference that will be called with
#pod three positional arguments:
#pod
#pod =for :list
#pod * an error string argument describing the error condition
#pod * a reference to the problematic document or byte-string
#pod * the method in which the error occurred (e.g. C<encode_one> or C<decode_one>)
#pod
#pod Note: for decoding errors, the byte-string is passed as a reference to avoid
#pod copying possibly large strings.
#pod
#pod If not provided, errors messages will be thrown with C<Carp::croak>.
#pod
#pod =cut
# XXX should this be separate for encode & decode? e.g. encode always want
# to throw with document and decode doesn't?
has
error_callback
=> (
is
=>
'ro'
,
isa
=> Maybe[CodeRef],
);
#pod =attr invalid_chars
#pod
#pod A string containing ASCII characters that must not appear in keys. The default
#pod is the empty string, meaning there are no invalid characters.
#pod
#pod =cut
has
invalid_chars
=> (
is
=>
'ro'
,
isa
=> Str,
default
=>
''
,
);
## XXX don't need this yet; do with 'invalid_chars' first for now
##
##=attr key_validator
##
##This attribute must be either a regular expresssion reference or
##a function reference to validate a key during encoding.
##
##A function reference will get a single string argument and must return
##an error string if the key is B<invalid>; if the key is B<valid> it must
##return B<nothing>.
##
##A regular expression will be matched against the key; if it matches, the
##key is valid.
##
##If not provided, any key is ok.
##
##=cut
##
##has key_validator => (
## is => 'ro',
## isa => Maybe[RegexpRef|CodeRef],
##);
##
## XXX don't need this until encode_many is implemented
##
##=attr max_batch_size
##
##This attribute defines the maximum number of documents to return in a chunk
##when using C<encode_many>. The default is 0, which disables any maximum.
##
##=cut
##
##has max_batch_size=> (
## is => 'ro',
## isa => NonNegNum,
## default => 0,
##);
## XXX don't need this until we have a back-end that isn't hard-coded
##
##=attr max_depth
##
##This attribute defines the maximum document depth allowed. The default
##is 100 for both encoding and decoding.
##
##This
##
##=cut
##
##has max_depth => (
## is => 'ro',
## isa => NonNegNum,
## default => 100,
##);
#pod =attr max_length
#pod
#pod This attribute defines the maximum document size. The default is 0, which
#pod disables any maximum.
#pod
#pod If set to a positive number, it applies to both encoding B<and> decoding (the
#pod latter is necessary for prevention of resource consumption attacks).
#pod
#pod =cut
has
max_length
=> (
is
=>
'ro'
,
isa
=> NonNegNum,
default
=> 0,
);
#pod =attr op_char
#pod
#pod This is a single character to use for special operators. If a key starts
#pod with C<op_char>, the C<op_char> character will be replaced with "$".
#pod
#pod The default is "$".
#pod
#pod =cut
has
op_char
=> (
is
=>
'ro'
,
isa
=> Maybe[ SingleChar ],
);
#pod =attr prefer_numeric
#pod
#pod If set to true, scalar values that look like a numeric value will be
#pod encoded as a BSON numeric type. When false, if the scalar value was ever
#pod used as a string, it will be encoded as a BSON UTF-8 string.
#pod
#pod The default is false.
#pod
#pod =cut
has
prefer_numeric
=> (
is
=>
'ro'
,
isa
=> Bool,
);
#--------------------------------------------------------------------------#
# public methods
#--------------------------------------------------------------------------#
#pod =method encode_one
#pod
#pod $byte_string = $codec->encode_one( $doc );
#pod $byte_string = $codec->encode_one( $doc, \%options );
#pod
#pod Takes a "document", typically a hash reference, an array reference, or a
#pod Tie::IxHash object and returns a byte string with the BSON representation of
#pod the document.
#pod
#pod An optional hash reference of options may be provided. Valid options include:
#pod
#pod =for :list
#pod * first_key – if C<first_key> is defined, it and C<first_value>
#pod will be encoded first in the output BSON; any matching key found in the
#pod document will be ignored.
#pod * first_value - value to assign to C<first_key>; will encode as Null if omitted
#pod * error_callback – overrides codec default
#pod * invalid_chars – overrides codec default
#pod * max_length – overrides codec default
#pod * op_char – overrides codec default
#pod * prefer_numeric – overrides codec default
#pod
#pod =cut
my
@encode_overrides
=
qw/error_callback invalid_chars max_length op_char prefer_numeric/
;
my
$encode_one_args
;
sub
encode_one {
$encode_one_args
||= compile( Object, Any, Optional [HashRef]);
my
(
$self
,
$document
,
$options
) =
$encode_one_args
->(
@_
);
for
my
$k
(
@encode_overrides
) {
$options
->{
$k
} =
$self
->
$k
unless
exists
$options
->{
$k
};
}
my
$bson
=
eval
{ MongoDB::BSON::_encode_bson(
$document
,
$options
) };
if
( $@ or (
$options
->{max_length} &&
length
(
$bson
) >
$options
->{max_length} ) ) {
my
$msg
= $@ ||
"Document exceeds maximum size $options->{max_length}"
;
if
(
$options
->{error_callback} ) {
$options
->{error_callback}->(
$msg
,
$document
,
'encode_one'
);
}
else
{
Carp::croak(
"During encode_one, $msg"
);
}
}
return
$bson
;
}
#pod =method decode_one
#pod
#pod $doc = $codec->decode_one( $byte_string );
#pod $doc = $codec->decode_one( $byte_string, \%options );
#pod
#pod Takes a byte string with a BSON-encoded document and returns a
#pod hash reference representin the decoded document.
#pod
#pod An optional hash reference of options may be provided. Valid options include:
#pod
#pod =for :list
#pod * dbref_callback – overrides codec default
#pod * dt_type – overrides codec default
#pod * error_callback – overrides codec default
#pod * max_length – overrides codec default
#pod
#pod =cut
my
@decode_overrides
=
qw/dbref_callback dt_type error_callback max_length/
;
my
$decode_one_args
;
sub
decode_one {
$decode_one_args
||= compile( Object, Str, Optional [HashRef] );
my
(
$self
,
$string
,
$options
) =
$decode_one_args
->(
@_
);
for
my
$k
(
@decode_overrides
) {
$options
->{
$k
} =
$self
->
$k
unless
exists
$options
->{
$k
};
}
if
(
$options
->{max_length} &&
length
(
$string
) >
$options
->{max_length} ) {
my
$msg
=
"Document exceeds maximum size $options->{max_length}"
;
if
(
$options
->{error_callback} ) {
$options
->{error_callback}->(
$msg
, \
$string
,
'decode_one'
);
}
else
{
Carp::croak(
"During decode_one, $msg"
);
}
}
my
$document
=
eval
{ MongoDB::BSON::_decode_bson(
$string
,
$options
) };
if
( $@ ) {
if
(
$options
->{error_callback} ) {
$options
->{error_callback}->( $@, \
$string
,
'decode_one'
);
}
else
{
Carp::croak(
"During decode_one, $@"
);
}
}
return
$document
;
}
#pod =method clone
#pod
#pod $codec->clone( dt_type => 'Time::Moment' );
#pod
#pod Constructs a copy of the original codec, but allows changing
#pod attributes in the copy.
#pod
#pod =cut
sub
clone {
my
(
$self
,
@args
) =
@_
;
my
$class
=
ref
(
$self
);
if
(
@args
== 1 &&
ref
(
$args
[0] ) eq
'HASH'
) {
return
$class
->new(
%$self
, %{
$args
[0]} );
}
return
$class
->new(
%$self
,
@args
);
}
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
MongoDB::BSON - Tools for serializing and deserializing data in BSON form
=head1 VERSION
version v0.999.999.2
=head1 SYNOPSIS
my $codec = MongoDB::BSON->new;
my $bson = $codec->encode_one( $document );
my $doc = $codec->decode_one( $bson );
=head1 DESCRIPTION
This class implements a BSON encoder/decoder ("codec"). It consumes documents
and emits BSON strings and vice versa.
=head1 ATTRIBUTES
=head2 dbref_callback
A document with keys C<$ref> and C<$id> is a special MongoDB convention
representing a
This attribute specifies a function reference that will be called with a hash
reference argument representing a DBRef.
The hash reference will have keys C<$ref> and C<$id> and may have C<$db> and
other keys. The callback must return a scalar value representing the dbref
(e.g. a document, an object, etc.)
The default returns the DBRef hash reference without modification.
=head2 dt_type
Sets the type of object which is returned for BSON DateTime fields. The default
is L<DateTime>. Other acceptable values are L<Time::Moment>, L<DateTime::Tiny>
and C<undef>. The latter will give you the raw epoch value rather than an
object.
# XXX add MongoDB::BSON::DateTime support and make it the default
=head2 error_callback
This attribute specifies a function reference that will be called with
three positional arguments:
=over 4
=item *
an error string argument describing the error condition
=item *
a reference to the problematic document or byte-string
=item *
the method in which the error occurred (e.g. C<encode_one> or C<decode_one>)
=back
Note: for decoding errors, the byte-string is passed as a reference to avoid
copying possibly large strings.
If not provided, errors messages will be thrown with C<Carp::croak>.
=head2 invalid_chars
A string containing ASCII characters that must not appear in keys. The default
is the empty string, meaning there are no invalid characters.
=head2 max_length
This attribute defines the maximum document size. The default is 0, which
disables any maximum.
If set to a positive number, it applies to both encoding B<and> decoding (the
latter is necessary for prevention of resource consumption attacks).
=head2 op_char
This is a single character to use for special operators. If a key starts
with C<op_char>, the C<op_char> character will be replaced with "$".
The default is "$".
=head2 prefer_numeric
If set to true, scalar values that look like a numeric value will be
encoded as a BSON numeric type. When false, if the scalar value was ever
used as a string, it will be encoded as a BSON UTF-8 string.
The default is false.
=head1 METHODS
=head2 encode_one
$byte_string = $codec->encode_one( $doc );
$byte_string = $codec->encode_one( $doc, \%options );
Takes a "document", typically a hash reference, an array reference, or a
Tie::IxHash object and returns a byte string with the BSON representation of
the document.
An optional hash reference of options may be provided. Valid options include:
=over 4
=item *
first_key – if C<first_key> is defined, it and C<first_value> will be encoded first in the output BSON; any matching key found in the document will be ignored.
=item *
first_value - value to assign to C<first_key>; will encode as Null if omitted
=item *
error_callback – overrides codec default
=item *
invalid_chars – overrides codec default
=item *
max_length – overrides codec default
=item *
op_char – overrides codec default
=item *
prefer_numeric – overrides codec default
=back
=head2 decode_one
$doc = $codec->decode_one( $byte_string );
$doc = $codec->decode_one( $byte_string, \%options );
Takes a byte string with a BSON-encoded document and returns a
hash reference representin the decoded document.
An optional hash reference of options may be provided. Valid options include:
=over 4
=item *
dbref_callback – overrides codec default
=item *
dt_type – overrides codec default
=item *
error_callback – overrides codec default
=item *
max_length – overrides codec default
=back
=head2 clone
$codec->clone( dt_type => 'Time::Moment' );
Constructs a copy of the original codec, but allows changing
attributes in the copy.
=head1 AUTHORS
=over 4
=item *
David Golden <david@mongodb.com>
=item *
Mike Friedman <friedo@friedo.com>
=item *
Kristina Chodorow <k.chodorow@gmail.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