#  Copyright (c) 1997-2021
#  Ewgenij Gawrilow, Michael Joswig, and the polymake team
#  Technische Universität Berlin, Germany
#  https://polymake.org
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the
#  Free Software Foundation; either version 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#-------------------------------------------------------------------------------
#
#  This file is part of the polymake database interface polyDB.
#
#   @author Silke Horn, Andreas Paffenholz
#   http://www.mathematik.tu-darmstadt.de/~paffenholz
#


# FIMXE page of Silke is gone!
# FIXME we need a page in the wiki

use namespaces qw(+ PolyDB);

CREDIT polyDB

package PolyDB::default;

# @category Database Access
# polyDB: The hostname of the database, default 'polymake.org'
custom $db_host = "db.polymake.org";

# polyDB: The port of the database, default 27017
custom $db_port = "27017";

# polyDB: The name of the database for the collections
custom $db_name = "polydb";

# polyDB: The database username, default 'polymake'
custom $db_user = "polymake";

# polyDB: The database password, default 'database'
custom $db_pwd = "database";

# polyDB: The name of the section you want to access. Set this if you want to access a certain section all (or most of) the time.
custom $db_section_name = "";

# polyDB: The name of the collection you want to access. Set this if you want to access a certain collection all (or most of) the time.
custom $db_collection_name = "";

# polyDB: the version of polyDB used
custom $db_polydb_version = "2.1";

# polyDB: The timeout for waiting to get a socket connection to the db server
custom $db_socket_timeout = 120000;

# polyDB: The color for section names in info output
custom $db_section_color = 'bold red';

# polyDB: The color for collection names in info output
custom $db_collection_color = 'bold yellow';

# polyDB: Whether to use SSL
custom $useSSL = 1;

# polyDB: whether some pretty printing shoudl be applied for the info method
#         needs to be switched off for testing
custom $pretty_print_doc = true;

# polyDB: The name of the authentication database, default 'admin'
custom $db_auth_db = "admin";

package PolyDB::Collection;

# @category Database Query Operations
# Common options for database queries
options %query_options = (
   # [complete PolyDB::query(grouped)] ARRAY sort returned objects by given properties
   #  sort criteria are specified as list of pairs (PROPERTY_NAME => 1|-1), -1 meaning descending order.
   #  By default, objects are sorted by _id
   sort_by => [ _id => 1 ],
   # [complete PolyDB::query(grouped)] HASH filter for properties in returned objects: { PROPERTY_NAME => 0|1, ... }
   #  All values in the filter must be either 0's or 1's.
   #  A filter with zero values suppresses the specified properties and allows all others,
   #  while a filter with ones allows the specified properties and suppresses all others.
   #  By default, objects are returned with all properties stored in the database.
   projection => undef,
   # [complete PolyDB::query(grouped)] Bool return objects as json
   raw => false
);

# @category Database Query Operations
# Options for database queries returning a cursor
options %cursor_options = (
   %query_options,
   # Int  maximal number of objects to be returned; by default, no limit
   limit => 0,
   # Int  skip that many first elements; default is 0
   skip => 0
);

# @category Database Query Operations
# Retrieve all objects satisfying the given search criteria
# @param [complete PolyDB::query(grouped)] HASH query search criteria written in Mongo query language
#  an empty hash map will retrieve all objects in this collection
# @options %cursor_options
# @return PolyDB::Cursor cursor over results
user_method find ($, %cursor_options) {
   my ($collection, $query, $options) = @_;
   return $collection->make_cursor($query, $options->{projection}, $options->{raw})->limit($options->{limit})->skip($options->{skip})->sort($options->{sort_by});
}

# @category Database Query Operations
# Retrieve the first object satisfying the given search criteria.
# @param [complete PolyDB::query(grouped)] HASH query search criteria written in Mongo query language
#  an empty hash map will retrieve a random object from this collection
# @return Core::BigObject
user_method find_one ($, \%query_options) {
   my ($collection, $query, $options) = @_;
   return $collection->find_one_impl($query, $options->{projection}, $options->{sort_by}, $options->{raw});
}

# @category Database Query Operations
# Retrieve a list of distinct values of a given property.
# The values are returned in arbitrary order.
# @param [complete PolyDB::query(grouped)] HASH query search criteria for objects to be inspected, written in Mongo query language
#  an empty hash map will collect property values from all objects in this collection
# @param [complete PolyDB::query] String property name of the property of interest
# @return ARRAY
user_method distinct ($$) { &distinct_impl }

# @category Database Query Operations
# Return the number of objects satisfying the given search criteria.
# @param [complete PolyDB::query(grouped)] HASH query search criteria written in Mongo query language
user_method count ($) { &count_impl }

# @category Database Query Operations
# Count the distinct property values in objects satisfying the given search criteria.
# @param [complete PolyDB::query(grouped)] HASH query search criteria for objects to be inspected, written in Mongo query language
#  an empty hash map will collect property values from all objects in this collection
# @param [complete PolyDB::query] String property name of the property of interest
user_method count_distinct ($$) {
   if (defined(my $result = count_distinct_impl(@_, "n"))) {
      $result->{n}
   } else {
      0
   }
}

# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
