
=pod

=head1 NAME

MongoDB::DataTypes - the data types used with MongoDB

=head1 DESCRIPTION

This goes over the types you can save to the database and use for queries.

=head1 TYPES

=head2 Dates

The L<DateTime> package can be used insert and query for dates. Dates stored in 
the database will be returned as instances of DateTime.

An example of storing and retrieving a date:

    use DateTime;

    my $now = DateTime->now;
    $collection->insert({'ts' => $now});

    my $obj = $collection->find_one;
    print "Today is ".$obj->{'ts'}->ymd."\n";

An example of querying for a range of dates:

    my $start = DateTime->from_epoch( epoch => 100000 );
    my $end = DateTime->from_epoch( epoch => 500000 );

    my $cursor = $collection->query({event => {'$gt' => $start, '$lt' => $end}});

=head2 Regular Expressions

Use C<qr/.../> to use a regular expression in a query:

    my $cursor = $collection->query({"name" => qr/[Jj]oh?n/});

Regular expressions will match strings saved in the database.

You can also save and retrieve regular expressions themselves:

    $collection->insert({"regex" => qr/foo/i});
    $obj = $collection->find_one;
    if ("FOO" =~ $obj->{'regex'}) { # matches
        print "hooray\n";
    }

Note for Perl 5.8 users: flags are lost when regular expressions are retrieved 
from the database (this does not affect queries or Perl 5.10).

=head2 Booleans

Use the L<boolean> pachage to get boolean values.  C<boolean::true> and 
C<boolean::false> are the only parts of the package used, currently.

An example of inserting boolean values:

    use boolean;

    $collection->insert({"okay" => true, "name" => "fred"});

An example using boolean values for query operators (only returns documents
where the name field exists):

    my $cursor = $collection->query({"name" => {'$exists' => boolean::true}});

=head2 Numbers

By default, numbers with a decimal point will be saved as doubles (64-bit).

=head3 32-bit Platforms

Numbers without decimal points will be saved as 32-bit integers.  To save a 
number as a 64-bit integer, use bigint:

    use bigint;

    $collection->insert({"user_id" => 28347197234178})

The driver will die if you try to insert a number beyond the signed 64-bit 
range: -9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.

Numbers that are saved as 64-bit integers will be decoded as doubles.

=head3 64-bit Platforms

Numbers without a decimal point will be saved and returned as 64-bit integers.

Keep in mind that this can cause some weirdness to ensue if some machines are
32-bit and others are 64-bit.  Take the following example:

=over 4

=item * Programmer 1 saves an int on a 32-bit platform.

=item * Programmer 2 retrieves the document on a 64-bit platform and re-saves it,
effectively converting it to a 64-bit int.

=item * Programmer 1 retrieves the document on their 32-bit machine, which decodes the
64-bit int as a double.

=back

Nothing drastic, but good to be aware of.

=head2 Other

There are a few Mongo-specific data types.

=head3 MongoDB::OID

"OID" stands for "Object ID", and is a unique id that is automatically added to 
documents if they do not already have an C<_id> field before they are saved to 
the database.  They are 12 bytes which are guarenteed to be unique.  Their 
string form is a 24-character string of hexidecimal digits.

To create a unique id:

    my $oid = MongoDB::OID->new;

To create a MongoDB::OID from an existing 24-character hexidecimal string:

    my $oid = MongoDB::OID->new("123456789012345678901234");

=head3 Binary Data

By default, all database strings are UTF8.  To save images, binaries, and other
non-UTF8 data, you can pass the string as a reference to the database.  For 
example:

    # non-utf8 string
    my $string = "\xFF\xFE\xFF";

    $collection->insert({"photo" => \$string});

This will save the variable as binary data, bypassing the UTF8 check.

=head3 MongoDB::Code

C<MongoDB::Code> is used to represent JavaScript code and, optionally, scope.
To create one:

    use MongoDB::Code;

    my $code = MongoDB::Code->new("code" => "function() { return 'hello, world'; }");

Or, with a scope:

    my $code = MongoDB::Code->new("code" => "function() { return 'hello, '+name; }",
        "scope" => "Fred");

Which would then return "hello, Fred" when run.

=head3 MongoDB::MinKey

MongoDB::MinKey is "less than" any other value of any type.  This can be useful
for always returning certain documents first (or last).

MongoDB::MinKey has no methods, fields, or string form.  To create one, it is
sufficient to say:

    bless $minKey, "MongoDB::MinKey";

=head3 MongoDB::MaxKey

MongoDB::MaxKey is "greater than" any other value of any type.  This can be useful
for always returning certain documents last (or first).

MongoDB::MaxKey has no methods, fields, or string form.  To create one, it is
sufficient to say:

    bless $minKey, "MongoDB::MaxKey";

