<commit_before>/*
 * Copyright (c) 2008-2015 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DATABASE_NODE_IMPL_HPP
#define DATABASE_NODE_IMPL_HPP

#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <set>
#include <string>

#include <boost/asio.hpp>

#include <database/stack.hpp>
#include <database/storage_node.hpp>

namespace database {

    class key_pool;
    class message;
    class node;
    class operation_queue;
    class routing_table;
    class storage;
    class tcp_acceptor;
    class tcp_connector;
    class udp_handler;
    class udp_multiplexor;

    /**
     * The node implementation.
     */
    class node_impl : public std::enable_shared_from_this<node_impl>
    {
        public:

            /**
             * Constructor
             * @param ios The boost::asio::io_service.
             * @param owner The node.
             */
            node_impl(boost::asio::io_service &, node &);

            /**
             * Starts the node implementation.
             * @param config The stack::configuration.
             */
            void start(const stack::configuration &);

            /**
             * Stops the node implementation.
             */
            void stop();

            /**
             * Performs a ping operation.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param snodes The storage_node's.
             */
            std::uint16_t ping(
                const boost::asio::ip::udp::endpoint &,
                std::vector<storage_node> snodes = std::vector<storage_node>()
            );

            /**
             * Queues a ping operation in the routing table.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param snodes The storage_node's.
             */
            void queue_ping(
                const boost::asio::ip::udp::endpoint &
            );

            /**
             * Performs a store operation.
             * @param query The query.
             */
            std::uint16_t store(const std::string &);

            /**
             * Performs a lookup on the query.
             * @param query The query.
             * @param max_results The maximum number of results.
             */
            std::uint16_t find(const std::string &, const std::size_t &);

            /**
             * Returns all of the endpoints in the routing table.
             */
            std::list< std::pair<std::string, std::uint16_t> > endpoints();

            /**
             * The stack::configuration.
             */
            stack::configuration & config();

            /**
             * The public boost::asio::ip::udp::endpoint.
             */
            boost::asio::ip::udp::endpoint & public_endpoint();

            /**
             * Sets the bootstrap contacts.
             * @param val The value.
             */
            void set_bootstrap_contacts(
                const std::list<boost::asio::ip::udp::endpoint> &
            );

            /**
             * The bootstrap contacts.
             */
            std::list<boost::asio::ip::udp::endpoint> & bootstrap_contacts();

            /**
             * The id.
             */
            const std::string & id() const;

            /**
             * Sends the given message to the boost::asio::ip::udp::endpoint.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void send_message(
                const boost::asio::ip::udp::endpoint &,
                std::shared_ptr<message>
            );

            /**
             * Handles a message.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param buf The buffer.
             * @param len The length
             */
            void handle_message(
                const boost::asio::ip::udp::endpoint &, const char *,
                const std::size_t &
            );

            /**
             * Called when an rpc receives a response.
             * @param oid The operation identifier.
             * @param tid The transaction identifier.
             * @param ep The boost::asio::ip::udp::endpoint.
             */
            void handle_rpc_response(
                const std::uint16_t &, const std::uint16_t &,
                const boost::asio::ip::udp::endpoint &
            );

            /**
             * Called when an rpc times out.
             * @param tid The transaction identifier.
             * @param node_id The node id.
             */
            void handle_rpc_timeout(
                const std::uint16_t &, const boost::asio::ip::udp::endpoint &
            );

            /**
             * Called when a udp packet doesn't match the protocol fingerprint.
             * @param addr The address.
             * @param port The port.
             * @param buf The buffer.
             * @param len The length.
             */
            void on_app_udp_receive(
                const char * addr, const std::uint16_t & port, const char * buf,
                const std::size_t & len
            );

        private:

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_ack_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_nack_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             * Handles a ping message.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_ping_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_store_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_find_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_probe_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_error_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             * The stack::configuration.
             */
            stack::configuration m_config;

            /**
             * The id.
             */
            std::string m_id;

            /**
             * The key_pool.
             */
            std::shared_ptr<key_pool> m_key_pool;

            /**
             * The public boost::asio::ip::udp::endpoint.
             */
            boost::asio::ip::udp::endpoint m_public_endpoint;

            /**
             * The bootstrap contacts.
             */
            std::list<boost::asio::ip::udp::endpoint> m_bootstrap_contacts;

            /**
             * The on find handler.
             */
            std::function<
                void (const std::uint16_t &, const std::string &,
                const std::string &, const std::uint32_t &)
            > m_on_find;

        protected:

            friend class ping_operation;
            friend class slot;

            /**
             * The node.
             */
            node & node_;

            /**
             * The boost::asio::io_service.
             */
            boost::asio::io_service & io_service_;

            /**
             * The boost::asio::io_service::stand.
             */
            boost::asio::io_service::strand strand_;

            /**
             * The public endpoint mutex.
             */
            std::recursive_mutex public_endpoint_mutex_;

            /**
             * The udp_multiplexor.
             */
            std::shared_ptr<udp_multiplexor> udp_multiplexor_;

            /**
             * The udp_handler.
             */
            std::shared_ptr<udp_handler> udp_handler_;

            /**
             * The routing_table.
             */
            std::shared_ptr<routing_table> routing_table_;

            /**
             * The operation_queue.
             */
            std::shared_ptr<operation_queue> operation_queue_;

            /**
             * The storage.
             */
            std::shared_ptr<storage> storage_;
    };

} // namespace database

#endif // DATABASE_NODE_IMPL_HPP
<commit_msg>integrating ecdhe into communications<commit_after>/*
 * Copyright (c) 2008-2015 John Connor (BM-NC49AxAjcqVcF5jNPu85Rb8MJ2d9JqZt)
 *
 * This is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DATABASE_NODE_IMPL_HPP
#define DATABASE_NODE_IMPL_HPP

#include <cstdint>
#include <functional>
#include <memory>
#include <mutex>
#include <set>
#include <string>

#include <boost/asio.hpp>

#include <database/stack.hpp>
#include <database/storage_node.hpp>

namespace database {

    class ecdhe;
    class key_pool;
    class message;
    class node;
    class operation_queue;
    class routing_table;
    class storage;
    class tcp_acceptor;
    class tcp_connector;
    class udp_handler;
    class udp_multiplexor;

    /**
     * The node implementation.
     */
    class node_impl : public std::enable_shared_from_this<node_impl>
    {
        public:

            /**
             * Constructor
             * @param ios The boost::asio::io_service.
             * @param owner The node.
             */
            node_impl(boost::asio::io_service &, node &);

            /**
             * Starts the node implementation.
             * @param config The stack::configuration.
             */
            void start(const stack::configuration &);

            /**
             * Stops the node implementation.
             */
            void stop();

            /**
             * Performs a ping operation.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param snodes The storage_node's.
             */
            std::uint16_t ping(
                const boost::asio::ip::udp::endpoint &,
                std::vector<storage_node> snodes = std::vector<storage_node>()
            );

            /**
             * Queues a ping operation in the routing table.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param snodes The storage_node's.
             */
            void queue_ping(
                const boost::asio::ip::udp::endpoint &
            );

            /**
             * Performs a store operation.
             * @param query The query.
             */
            std::uint16_t store(const std::string &);

            /**
             * Performs a lookup on the query.
             * @param query The query.
             * @param max_results The maximum number of results.
             */
            std::uint16_t find(const std::string &, const std::size_t &);

            /**
             * Returns all of the endpoints in the routing table.
             */
            std::list< std::pair<std::string, std::uint16_t> > endpoints();

            /**
             * The stack::configuration.
             */
            stack::configuration & config();

            /**
             * The public boost::asio::ip::udp::endpoint.
             */
            boost::asio::ip::udp::endpoint & public_endpoint();

            /**
             * Sets the bootstrap contacts.
             * @param val The value.
             */
            void set_bootstrap_contacts(
                const std::list<boost::asio::ip::udp::endpoint> &
            );

            /**
             * The bootstrap contacts.
             */
            std::list<boost::asio::ip::udp::endpoint> & bootstrap_contacts();

            /**
             * The id.
             */
            const std::string & id() const;

            /**
             * The ecdhe.
             */
            std::shared_ptr<ecdhe> & get_ecdhe();

            /**
             * Sends the given message to the boost::asio::ip::udp::endpoint.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void send_message(
                const boost::asio::ip::udp::endpoint &,
                std::shared_ptr<message>
            );

            /**
             * Handles a message.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param buf The buffer.
             * @param len The length
             */
            void handle_message(
                const boost::asio::ip::udp::endpoint &, const char *,
                const std::size_t &
            );

            /**
             * Called when an rpc receives a response.
             * @param oid The operation identifier.
             * @param tid The transaction identifier.
             * @param ep The boost::asio::ip::udp::endpoint.
             */
            void handle_rpc_response(
                const std::uint16_t &, const std::uint16_t &,
                const boost::asio::ip::udp::endpoint &
            );

            /**
             * Called when an rpc times out.
             * @param tid The transaction identifier.
             * @param node_id The node id.
             */
            void handle_rpc_timeout(
                const std::uint16_t &, const boost::asio::ip::udp::endpoint &
            );

            /**
             * Called when a udp packet doesn't match the protocol fingerprint.
             * @param addr The address.
             * @param port The port.
             * @param buf The buffer.
             * @param len The length.
             */
            void on_app_udp_receive(
                const char * addr, const std::uint16_t & port, const char * buf,
                const std::size_t & len
            );

        private:

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_ack_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_nack_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             * Handles a ping message.
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_ping_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_store_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_find_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_probe_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             *
             * @param ep The boost::asio::ip::udp::endpoint.
             * @param msg The message.
             */
            void handle_error_message(
                const boost::asio::ip::udp::endpoint & ep, message & msg
            );

            /**
             * The stack::configuration.
             */
            stack::configuration m_config;

            /**
             * The id.
             */
            std::string m_id;

            /**
             * The ecdhe.
             */
            std::shared_ptr<ecdhe> m_ecdhe;

            /**
             * The key_pool.
             */
            std::shared_ptr<key_pool> m_key_pool;

            /**
             * The public boost::asio::ip::udp::endpoint.
             */
            boost::asio::ip::udp::endpoint m_public_endpoint;

            /**
             * The bootstrap contacts.
             */
            std::list<boost::asio::ip::udp::endpoint> m_bootstrap_contacts;

            /**
             * The on find handler.
             */
            std::function<
                void (const std::uint16_t &, const std::string &,
                const std::string &, const std::uint32_t &)
            > m_on_find;

        protected:

            friend class ping_operation;
            friend class slot;

            /**
             * The node.
             */
            node & node_;

            /**
             * The boost::asio::io_service.
             */
            boost::asio::io_service & io_service_;

            /**
             * The boost::asio::io_service::stand.
             */
            boost::asio::io_service::strand strand_;

            /**
             * The public endpoint mutex.
             */
            std::recursive_mutex public_endpoint_mutex_;

            /**
             * The udp_multiplexor.
             */
            std::shared_ptr<udp_multiplexor> udp_multiplexor_;

            /**
             * The udp_handler.
             */
            std::shared_ptr<udp_handler> udp_handler_;

            /**
             * The routing_table.
             */
            std::shared_ptr<routing_table> routing_table_;

            /**
             * The operation_queue.
             */
            std::shared_ptr<operation_queue> operation_queue_;

            /**
             * The storage.
             */
            std::shared_ptr<storage> storage_;
    };

} // namespace database

#endif // DATABASE_NODE_IMPL_HPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: datasourceui.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-01 15:10:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef DBACCESS_DATASOURCEUI_HXX
#define DBACCESS_DATASOURCEUI_HXX

#include "dsntypes.hxx"
#include "dsmeta.hxx"

/** === begin UNO includes === **/
/** === end UNO includes === **/

#include <boost/shared_ptr.hpp>

//........................................................................
namespace dbaui
{
//........................................................................

    //====================================================================
    //= DataSourceUI
    //====================================================================
    /** encapsulates information about available UI features of a data source type
    */
    class DataSourceUI
    {
    public:
        DataSourceUI( DATASOURCE_TYPE _eType );
        DataSourceUI( const DataSourceMetaData& _rDSMeta );
        ~DataSourceUI();

        /** returns whether the data source's UI contains the specified setting

            Note that at the moment, not all items are supported by this method. In particular, use
            it for the following only

All items which refer to advanced settings (see AdvancedSettingsSupport)

            A complete support of *all* items is a medium-term goal.

            @param _nItemId
                the UI's item ID for the setting in question. See dsitems.hxx.
        */
        bool    hasSetting( const USHORT _nItemId ) const;

    private:
        DataSourceMetaData  m_aDSMeta;
    };

//........................................................................
} // namespace dbaui
//........................................................................

#endif // DBACCESS_DATASOURCEUI_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.2.96); FILE MERGED 2008/03/31 13:27:15 rt 1.2.96.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: datasourceui.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef DBACCESS_DATASOURCEUI_HXX
#define DBACCESS_DATASOURCEUI_HXX

#include "dsntypes.hxx"
#include "dsmeta.hxx"

/** === begin UNO includes === **/
/** === end UNO includes === **/

#include <boost/shared_ptr.hpp>

//........................................................................
namespace dbaui
{
//........................................................................

    //====================================================================
    //= DataSourceUI
    //====================================================================
    /** encapsulates information about available UI features of a data source type
    */
    class DataSourceUI
    {
    public:
        DataSourceUI( DATASOURCE_TYPE _eType );
        DataSourceUI( const DataSourceMetaData& _rDSMeta );
        ~DataSourceUI();

        /** returns whether the data source's UI contains the specified setting

            Note that at the moment, not all items are supported by this method. In particular, use
            it for the following only

All items which refer to advanced settings (see AdvancedSettingsSupport)

            A complete support of *all* items is a medium-term goal.

            @param _nItemId
                the UI's item ID for the setting in question. See dsitems.hxx.
        */
        bool    hasSetting( const USHORT _nItemId ) const;

    private:
        DataSourceMetaData  m_aDSMeta;
    };

//........................................................................
} // namespace dbaui
//........................................................................

#endif // DBACCESS_DATASOURCEUI_HXX
<|endoftext|>


<commit_before>#include "greedy_operator_ordering.hpp"

#include "cost_estimation/abstract_cost_estimator.hpp"
#include "enumerate_ccp.hpp"
#include "join_graph.hpp"
#include "logical_query_plan/lqp_utils.hpp"
#include "operators/operator_join_predicate.hpp"
#include "statistics/cardinality_estimator.hpp"
#include "utils/format_duration.hpp"
#include "utils/timer.hpp"

namespace opossum {

std::shared_ptr<AbstractLQPNode> AbstractJoinOrderingAlgorithm::_add_predicates_to_plan(
    const std::shared_ptr<AbstractLQPNode>& lqp, const std::vector<std::shared_ptr<AbstractExpression>>& predicates,
    const std::shared_ptr<AbstractCostEstimator>& cost_estimator) const {
  /**
   * Add a number of predicates on top of a plan; try to bring them into an efficient order
   *
   *
   * The optimality-ensuring way to sort the scan operations would be to find the cheapest of the predicates.size()!
   * orders of them.
   * For now, we just execute the scan operations in the order of increasing cost that they would have when executed
   * directly on top of `lqp`
   */

  if (predicates.empty()) return lqp;

  auto predicate_nodes_and_cost = std::vector<std::pair<std::shared_ptr<AbstractLQPNode>, Cost>>{};
  predicate_nodes_and_cost.reserve(predicates.size());
  for (const auto& predicate : predicates) {
    const auto predicate_node = PredicateNode::make(predicate, lqp);
    predicate_nodes_and_cost.emplace_back(predicate_node, cost_estimator->estimate_node_cost(predicate_node));
  }

  std::sort(predicate_nodes_and_cost.begin(), predicate_nodes_and_cost.end(),
            [&](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });

  predicate_nodes_and_cost.front().first->set_left_input(lqp);

  for (auto predicate_node_idx = size_t{1}; predicate_node_idx < predicate_nodes_and_cost.size();
       ++predicate_node_idx) {
    predicate_nodes_and_cost[predicate_node_idx].first->set_left_input(
        predicate_nodes_and_cost[predicate_node_idx - 1].first);
  }

  return predicate_nodes_and_cost.back().first;
}

std::shared_ptr<AbstractLQPNode> AbstractJoinOrderingAlgorithm::_add_join_to_plan(
    const std::shared_ptr<AbstractLQPNode>& left_lqp, const std::shared_ptr<AbstractLQPNode>& right_lqp,
    std::vector<std::shared_ptr<AbstractExpression>> join_predicates,
    const std::shared_ptr<AbstractCostEstimator>& cost_estimator) const {
  /**
   * Join two plans using a set of predicates; try to bring them into an efficient order
   *
   *
   * One predicate ("primary predicate") becomes the join predicate, the others ("secondary predicates) are executed as
   * column-to-column scans after the join.
   * The primary predicate needs to be a simple "<column> <operator> <column>" predicate, otherwise the join operators
   * won't be able to execute it.
   *
   * The optimality-ensuring way to order the predicates would be to find the cheapest of the predicates.size()!
   * orders of them.
   * For now, we just execute the scan operations in the order of increasing cost that they would have when executed
   * directly on top of `lqp`, with the cheapest predicate becoming the primary predicate.
   */

  // Sort the predicates by increasing cost
  auto join_predicates_and_cost = std::vector<std::pair<std::shared_ptr<AbstractExpression>, Cost>>{};
  join_predicates_and_cost.reserve(join_predicates.size());
  for (const auto& join_predicate : join_predicates) {
    const auto join_node = JoinNode::make(JoinMode::Inner, join_predicate, left_lqp, right_lqp);
    const auto cost = cost_estimator->estimate_node_cost(join_node);
    join_predicates_and_cost.emplace_back(join_predicate, cost);
  }

  std::sort(join_predicates_and_cost.begin(), join_predicates_and_cost.end(),
            [&](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });

  // Categorize join predicates into those that can be processed as part of a join operator and those that need to be
  // processed as normal predicates.
  // NOTE: Since a multi-predicate join is currently slower than scanning the join output table, we do not emit multiple
  //       predicates for the JoinNode, but use subsequent scans instead.
  auto join_node_predicates = std::vector<std::shared_ptr<AbstractExpression>>{};
  auto post_join_node_predicates = std::vector<std::shared_ptr<AbstractExpression>>{};

  for (const auto& [join_predicate, cost] : join_predicates_and_cost) {
    const auto operator_join_predicate = OperatorJoinPredicate::from_expression(*join_predicate, *left_lqp, *right_lqp);
    if (operator_join_predicate && join_node_predicates.empty()) {
      join_node_predicates.emplace_back(join_predicate);
    } else {
      post_join_node_predicates.emplace_back(join_predicate);
    }
  }

  // Build JoinNode (for primary predicate and secondary predicates)
  auto lqp = std::shared_ptr<AbstractLQPNode>{};
  if (!join_node_predicates.empty()) {
    lqp = JoinNode::make(JoinMode::Inner, join_node_predicates, left_lqp, right_lqp);
  } else {
    lqp = JoinNode::make(JoinMode::Cross, left_lqp, right_lqp);
  }

  // Post-JoinNode predicates are handled as normal predicates
  for (const auto& post_join_predicate : post_join_node_predicates) {
    lqp = PredicateNode::make(post_join_predicate, lqp);
  }

  return lqp;
}

}  // namespace opossum
<commit_msg>Update multi-predicate-join comment (#1834)<commit_after>#include "greedy_operator_ordering.hpp"

#include "cost_estimation/abstract_cost_estimator.hpp"
#include "enumerate_ccp.hpp"
#include "join_graph.hpp"
#include "logical_query_plan/lqp_utils.hpp"
#include "operators/operator_join_predicate.hpp"
#include "statistics/cardinality_estimator.hpp"
#include "utils/format_duration.hpp"
#include "utils/timer.hpp"

namespace opossum {

std::shared_ptr<AbstractLQPNode> AbstractJoinOrderingAlgorithm::_add_predicates_to_plan(
    const std::shared_ptr<AbstractLQPNode>& lqp, const std::vector<std::shared_ptr<AbstractExpression>>& predicates,
    const std::shared_ptr<AbstractCostEstimator>& cost_estimator) const {
  /**
   * Add a number of predicates on top of a plan; try to bring them into an efficient order
   *
   *
   * The optimality-ensuring way to sort the scan operations would be to find the cheapest of the predicates.size()!
   * orders of them.
   * For now, we just execute the scan operations in the order of increasing cost that they would have when executed
   * directly on top of `lqp`
   */

  if (predicates.empty()) return lqp;

  auto predicate_nodes_and_cost = std::vector<std::pair<std::shared_ptr<AbstractLQPNode>, Cost>>{};
  predicate_nodes_and_cost.reserve(predicates.size());
  for (const auto& predicate : predicates) {
    const auto predicate_node = PredicateNode::make(predicate, lqp);
    predicate_nodes_and_cost.emplace_back(predicate_node, cost_estimator->estimate_node_cost(predicate_node));
  }

  std::sort(predicate_nodes_and_cost.begin(), predicate_nodes_and_cost.end(),
            [&](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });

  predicate_nodes_and_cost.front().first->set_left_input(lqp);

  for (auto predicate_node_idx = size_t{1}; predicate_node_idx < predicate_nodes_and_cost.size();
       ++predicate_node_idx) {
    predicate_nodes_and_cost[predicate_node_idx].first->set_left_input(
        predicate_nodes_and_cost[predicate_node_idx - 1].first);
  }

  return predicate_nodes_and_cost.back().first;
}

std::shared_ptr<AbstractLQPNode> AbstractJoinOrderingAlgorithm::_add_join_to_plan(
    const std::shared_ptr<AbstractLQPNode>& left_lqp, const std::shared_ptr<AbstractLQPNode>& right_lqp,
    std::vector<std::shared_ptr<AbstractExpression>> join_predicates,
    const std::shared_ptr<AbstractCostEstimator>& cost_estimator) const {
  /**
   * Join two plans using a set of predicates; try to bring them into an efficient order
   *
   *
   * One predicate ("primary predicate") becomes the join predicate, the others ("secondary predicates) are executed as
   * column-to-column scans after the join.
   * The primary predicate needs to be a simple "<column> <operator> <column>" predicate, otherwise the join operators
   * won't be able to execute it.
   *
   * The optimality-ensuring way to order the predicates would be to find the cheapest of the predicates.size()!
   * orders of them.
   * For now, we just execute the scan operations in the order of increasing cost that they would have when executed
   * directly on top of `lqp`, with the cheapest predicate becoming the primary predicate.
   */

  // Sort the predicates by increasing cost
  auto join_predicates_and_cost = std::vector<std::pair<std::shared_ptr<AbstractExpression>, Cost>>{};
  join_predicates_and_cost.reserve(join_predicates.size());
  for (const auto& join_predicate : join_predicates) {
    const auto join_node = JoinNode::make(JoinMode::Inner, join_predicate, left_lqp, right_lqp);
    const auto cost = cost_estimator->estimate_node_cost(join_node);
    join_predicates_and_cost.emplace_back(join_predicate, cost);
  }

  std::sort(join_predicates_and_cost.begin(), join_predicates_and_cost.end(),
            [&](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });

  // Categorize join predicates into those that MUST be processed as part of a join operator (because they are required
  // to see if an outer join emits a value or a NULL) and those that can also be processed as regular predicates after
  // the join predicates (post-join predicates, e.g., additional join predicates for inner joins). Since the
  // multi-predicate join is currently slower than a regular predicate (i.e., a full table scan), we only use it in
  // cases where it is required for a correct result.
  auto join_node_predicates = std::vector<std::shared_ptr<AbstractExpression>>{};
  auto post_join_node_predicates = std::vector<std::shared_ptr<AbstractExpression>>{};

  for (const auto& [join_predicate, cost] : join_predicates_and_cost) {
    const auto operator_join_predicate = OperatorJoinPredicate::from_expression(*join_predicate, *left_lqp, *right_lqp);
    if (operator_join_predicate && join_node_predicates.empty()) {
      join_node_predicates.emplace_back(join_predicate);
    } else {
      post_join_node_predicates.emplace_back(join_predicate);
    }
  }

  // Build JoinNode (for primary predicate and secondary predicates)
  auto lqp = std::shared_ptr<AbstractLQPNode>{};
  if (!join_node_predicates.empty()) {
    lqp = JoinNode::make(JoinMode::Inner, join_node_predicates, left_lqp, right_lqp);
  } else {
    lqp = JoinNode::make(JoinMode::Cross, left_lqp, right_lqp);
  }

  // Post-JoinNode predicates are handled as normal predicates
  for (const auto& post_join_predicate : post_join_node_predicates) {
    lqp = PredicateNode::make(post_join_predicate, lqp);
  }

  return lqp;
}

}  // namespace opossum
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013-2017 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "context_p.h"

#include "common.h"
#include "request.h"
#include "response.h"
#include "action.h"
#include "dispatcher.h"
#include "controller.h"
#include "application.h"
#include "stats.h"
#include "enginerequest.h"

#include "config.h"

#include <QUrl>
#include <QUrlQuery>
#include <QCoreApplication>
#include <QBuffer>

using namespace Cutelyst;

Context::Context(ContextPrivate *priv) : d_ptr(priv)
{
}

Context::Context(Application *app) :
    d_ptr(new ContextPrivate(app, app->engine(), app->dispatcher(), app->plugins()))
{
    d_ptr->response = new Response(this, d_ptr->engine, app->defaultHeaders());

    DummyRequest req(app->engine(), this);
    req.body = new QBuffer(this);
    req.body->open(QBuffer::ReadWrite);

    d_ptr->request = new Request(new RequestPrivate(nullptr));
    d_ptr->request->setParent(this);
}

Context::~Context()
{
    delete d_ptr;
}

bool Context::error() const
{
    Q_D(const Context);
    return !d->error.isEmpty();
}

void Context::error(const QString &error)
{
    Q_D(Context);
    if (error.isEmpty()) {
        d->error.clear();
    } else {
        d->error << error;
        qCCritical(CUTELYST_CORE) << error;
    }
}

QStringList Context::errors() const
{
    Q_D(const Context);
    return d->error;
}

bool Context::state() const
{
    Q_D(const Context);
    return d->state;
}

void Context::setState(bool state)
{
    Q_D(Context);
    d->state = state;
}

Engine *Context::engine() const
{
    Q_D(const Context);
    return d->engine;
}

Application *Context::app() const
{
    Q_D(const Context);
    return d->app;
}

Response *Context::response() const
{
    Q_D(const Context);
    return d->response;
}

Response *Context::res() const
{
    Q_D(const Context);
    return d->response;
}

Action *Context::action() const
{
    Q_D(const Context);
    return d->action;
}

QString Context::actionName() const
{
    Q_D(const Context);
    return d->action->name();
}

QString Context::ns() const
{
    Q_D(const Context);
    return d->action->ns();
}

Request *Context::request() const
{
    Q_D(const Context);
    return d->request;
}

Request *Context::req() const
{
    Q_D(const Context);
    return d->request;
}

Dispatcher *Context::dispatcher() const
{
    Q_D(const Context);
    return d->dispatcher;
}

QString Cutelyst::Context::controllerName() const
{
    Q_D(const Context);
    return QString::fromLatin1(d->action->controller()->metaObject()->className());
}

Controller *Context::controller() const
{
    Q_D(const Context);
    return d->action->controller();
}

Controller *Context::controller(const QString &name) const
{
    Q_D(const Context);
    return d->dispatcher->controllers().value(name);
}

View *Context::view() const
{
    Q_D(const Context);
    return d->view;
}

View *Context::view(const QString &name) const
{
    Q_D(const Context);
    return d->app->view(name);
}

bool Context::setView(const QString &name)
{
    Q_D(Context);
    d->view = d->app->view(name);
    return d->view;
}

QVariantHash &Context::stash()
{
    Q_D(Context);
    return d->stash;
}

QVariant Context::stash(const QString &key) const
{
    Q_D(const Context);
    return d->stash.value(key);
}

void Context::setStash(const QString &key, const QVariant &value)
{
    Q_D(Context);
    d->stash.insert(key, value);
}

void Context::setStash(const QString &key, const ParamsMultiMap &map)
{
    Q_D(Context);
    d->stash.insert(key, QVariant::fromValue(map));
}

QStack<Component *> Context::stack() const
{
    Q_D(const Context);
    return d->stack;
}

QUrl Context::uriFor(const QString &path, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri = d->request->uri();

    QString _path = path;
    if (_path.isEmpty()) {
        // ns must NOT return a leading slash
        _path = QLatin1Char('/') + d->action->controller()->ns();
    } else if (!_path.startsWith(QLatin1Char('/'))) {
        _path.prepend(QLatin1Char('/'));
    }

    if (!args.isEmpty()) {
        _path = _path + QLatin1Char('/') + args.join(QLatin1Char('/'));
    }
    uri.setPath(_path, QUrl::DecodedMode);

    QUrlQuery query;
    if (!queryValues.isEmpty()) {
        // Avoid a trailing '?'
        if (queryValues.size()) {
            auto it = queryValues.constBegin();
            const auto end = queryValues.constEnd();
            while (it != end) {
                query.addQueryItem(it.key(), it.value());
                ++it;
            }
        }
    }
    uri.setQuery(query);

    return uri;
}

QUrl Context::uriFor(Action *action, const QStringList &captures, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri;
    Action *localAction = action;
    if (!localAction) {
        localAction = d->action;
    }

    QStringList localArgs = args;
    QStringList localCaptures = captures;

    Action *expandedAction = d->dispatcher->expandAction(this, action);
    if (expandedAction->numberOfCaptures() > 0) {
        while (localCaptures.size() < expandedAction->numberOfCaptures()
               && localArgs.size()) {
            localCaptures.append(localArgs.takeFirst());
        }
    } else {
        QStringList localCapturesAux = localCaptures;
        localCapturesAux.append(localArgs);
        localArgs = localCapturesAux;
        localCaptures = QStringList();
    }

    const QString path = d->dispatcher->uriForAction(localAction, localCaptures);
    if (path.isEmpty()) {
        qCWarning(CUTELYST_CORE) << "Can not find action for" << localAction << localCaptures;
        return uri;
    }

    uri = uriFor(path, localArgs, queryValues);
    return uri;
}

QUrl Context::uriForAction(const QString &path, const QStringList &captures, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri;
    Action *action = d->dispatcher->getActionByPath(path);
    if (!action) {
        qCWarning(CUTELYST_CORE) << "Can not find action for" << path;
        return uri;
    }

    uri = uriFor(action, captures, args, queryValues);
    return uri;
}

bool Context::detached() const
{
    Q_D(const Context);
    return d->detached;
}

void Context::detach(Action *action)
{
    Q_D(Context);
    if (action) {
        d->dispatcher->forward(this, action);
    }
    d->detached = true;
}

bool Context::forward(Component *action)
{
    Q_D(Context);
    return d->dispatcher->forward(this, action);
}

bool Context::forward(const QString &action)
{
    Q_D(Context);
    return d->dispatcher->forward(this, action);
}

Action *Context::getAction(const QString &action, const QString &ns) const
{
    Q_D(const Context);
    return d->dispatcher->getAction(action, ns);
}

QVector<Action *> Context::getActions(const QString &action, const QString &ns) const
{
    Q_D(const Context);
    return d->dispatcher->getActions(action, ns);
}

QVector<Cutelyst::Plugin *> Context::plugins() const
{
    Q_D(const Context);
    return d->plugins;
}

bool Context::execute(Component *code)
{
    Q_D(Context);
    Q_ASSERT_X(code, "Context::execute", "trying to execute a null Cutelyst::Component");

    static int recursion = qEnvironmentVariableIsSet("RECURSION") ? qEnvironmentVariableIntValue("RECURSION") : 1000;
    if (d->stack.size() >= recursion) {
        QString msg = QStringLiteral("Deep recursion detected (stack size %1) calling %2, %3")
                .arg(QString::number(d->stack.size()), code->reverse(), code->name());
        error(msg);
        setState(false);
        return false;
    }

    bool ret;
    d->stack.push(code);

    if (d->stats) {
        const QString statsInfo = d->statsStartExecute(code);

        ret = code->execute(this);

        if (!statsInfo.isEmpty()) {
            d->statsFinishExecute(statsInfo);
        }
    } else {
        ret = code->execute(this);
    }

    d->stack.pop();

    return ret;
}

QLocale Context::locale() const
{
    Q_D(const Context);
    return d->locale;
}

void Context::setLocale(const QLocale &locale)
{
    Q_D(Context);
    d->locale = locale;
}

QVariant Context::config(const QString &key, const QVariant &defaultValue) const
{
    Q_D(const Context);
    return d->app->config(key, defaultValue);
}

QVariantMap Context::config() const
{
    Q_D(const Context);
    return d->app->config();
}

QString Context::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const
{
    Q_D(const Context);
    return d->app->translate(d->locale, context, sourceText, disambiguation, n);
}

QString ContextPrivate::statsStartExecute(Component *code)
{
    QString actionName;
    // Skip internal actions
    if (code->name().startsWith(QLatin1Char('_'))) {
        return actionName;
    }

    actionName = code->reverse();

    if (dynamic_cast<Action *>(code)) {
        actionName.prepend(QLatin1Char('/'));
    }

    if (stack.size() > 2) {
        actionName = QLatin1String("-> ") + actionName;
        actionName = actionName.rightJustified(actionName.size() + stack.size() - 2, QLatin1Char(' '));
    }

    stats->profileStart(actionName);

    return actionName;
}

void ContextPrivate::statsFinishExecute(const QString &statsInfo)
{
    stats->profileEnd(statsInfo);
}

#include "moc_context.cpp"
#include "moc_context_p.cpp"
<commit_msg>Replace dynamic_cast with lighter qobject_cast<commit_after>/*
 * Copyright (C) 2013-2017 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "context_p.h"

#include "common.h"
#include "request.h"
#include "response.h"
#include "action.h"
#include "dispatcher.h"
#include "controller.h"
#include "application.h"
#include "stats.h"
#include "enginerequest.h"

#include "config.h"

#include <QUrl>
#include <QUrlQuery>
#include <QCoreApplication>
#include <QBuffer>

using namespace Cutelyst;

Context::Context(ContextPrivate *priv) : d_ptr(priv)
{
}

Context::Context(Application *app) :
    d_ptr(new ContextPrivate(app, app->engine(), app->dispatcher(), app->plugins()))
{
    d_ptr->response = new Response(this, d_ptr->engine, app->defaultHeaders());

    DummyRequest req(app->engine(), this);
    req.body = new QBuffer(this);
    req.body->open(QBuffer::ReadWrite);

    d_ptr->request = new Request(new RequestPrivate(nullptr));
    d_ptr->request->setParent(this);
}

Context::~Context()
{
    delete d_ptr;
}

bool Context::error() const
{
    Q_D(const Context);
    return !d->error.isEmpty();
}

void Context::error(const QString &error)
{
    Q_D(Context);
    if (error.isEmpty()) {
        d->error.clear();
    } else {
        d->error << error;
        qCCritical(CUTELYST_CORE) << error;
    }
}

QStringList Context::errors() const
{
    Q_D(const Context);
    return d->error;
}

bool Context::state() const
{
    Q_D(const Context);
    return d->state;
}

void Context::setState(bool state)
{
    Q_D(Context);
    d->state = state;
}

Engine *Context::engine() const
{
    Q_D(const Context);
    return d->engine;
}

Application *Context::app() const
{
    Q_D(const Context);
    return d->app;
}

Response *Context::response() const
{
    Q_D(const Context);
    return d->response;
}

Response *Context::res() const
{
    Q_D(const Context);
    return d->response;
}

Action *Context::action() const
{
    Q_D(const Context);
    return d->action;
}

QString Context::actionName() const
{
    Q_D(const Context);
    return d->action->name();
}

QString Context::ns() const
{
    Q_D(const Context);
    return d->action->ns();
}

Request *Context::request() const
{
    Q_D(const Context);
    return d->request;
}

Request *Context::req() const
{
    Q_D(const Context);
    return d->request;
}

Dispatcher *Context::dispatcher() const
{
    Q_D(const Context);
    return d->dispatcher;
}

QString Cutelyst::Context::controllerName() const
{
    Q_D(const Context);
    return QString::fromLatin1(d->action->controller()->metaObject()->className());
}

Controller *Context::controller() const
{
    Q_D(const Context);
    return d->action->controller();
}

Controller *Context::controller(const QString &name) const
{
    Q_D(const Context);
    return d->dispatcher->controllers().value(name);
}

View *Context::view() const
{
    Q_D(const Context);
    return d->view;
}

View *Context::view(const QString &name) const
{
    Q_D(const Context);
    return d->app->view(name);
}

bool Context::setView(const QString &name)
{
    Q_D(Context);
    d->view = d->app->view(name);
    return d->view;
}

QVariantHash &Context::stash()
{
    Q_D(Context);
    return d->stash;
}

QVariant Context::stash(const QString &key) const
{
    Q_D(const Context);
    return d->stash.value(key);
}

void Context::setStash(const QString &key, const QVariant &value)
{
    Q_D(Context);
    d->stash.insert(key, value);
}

void Context::setStash(const QString &key, const ParamsMultiMap &map)
{
    Q_D(Context);
    d->stash.insert(key, QVariant::fromValue(map));
}

QStack<Component *> Context::stack() const
{
    Q_D(const Context);
    return d->stack;
}

QUrl Context::uriFor(const QString &path, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri = d->request->uri();

    QString _path = path;
    if (_path.isEmpty()) {
        // ns must NOT return a leading slash
        _path = QLatin1Char('/') + d->action->controller()->ns();
    } else if (!_path.startsWith(QLatin1Char('/'))) {
        _path.prepend(QLatin1Char('/'));
    }

    if (!args.isEmpty()) {
        _path = _path + QLatin1Char('/') + args.join(QLatin1Char('/'));
    }
    uri.setPath(_path, QUrl::DecodedMode);

    QUrlQuery query;
    if (!queryValues.isEmpty()) {
        // Avoid a trailing '?'
        if (queryValues.size()) {
            auto it = queryValues.constBegin();
            const auto end = queryValues.constEnd();
            while (it != end) {
                query.addQueryItem(it.key(), it.value());
                ++it;
            }
        }
    }
    uri.setQuery(query);

    return uri;
}

QUrl Context::uriFor(Action *action, const QStringList &captures, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri;
    Action *localAction = action;
    if (!localAction) {
        localAction = d->action;
    }

    QStringList localArgs = args;
    QStringList localCaptures = captures;

    Action *expandedAction = d->dispatcher->expandAction(this, action);
    if (expandedAction->numberOfCaptures() > 0) {
        while (localCaptures.size() < expandedAction->numberOfCaptures()
               && localArgs.size()) {
            localCaptures.append(localArgs.takeFirst());
        }
    } else {
        QStringList localCapturesAux = localCaptures;
        localCapturesAux.append(localArgs);
        localArgs = localCapturesAux;
        localCaptures = QStringList();
    }

    const QString path = d->dispatcher->uriForAction(localAction, localCaptures);
    if (path.isEmpty()) {
        qCWarning(CUTELYST_CORE) << "Can not find action for" << localAction << localCaptures;
        return uri;
    }

    uri = uriFor(path, localArgs, queryValues);
    return uri;
}

QUrl Context::uriForAction(const QString &path, const QStringList &captures, const QStringList &args, const ParamsMultiMap &queryValues) const
{
    Q_D(const Context);

    QUrl uri;
    Action *action = d->dispatcher->getActionByPath(path);
    if (!action) {
        qCWarning(CUTELYST_CORE) << "Can not find action for" << path;
        return uri;
    }

    uri = uriFor(action, captures, args, queryValues);
    return uri;
}

bool Context::detached() const
{
    Q_D(const Context);
    return d->detached;
}

void Context::detach(Action *action)
{
    Q_D(Context);
    if (action) {
        d->dispatcher->forward(this, action);
    }
    d->detached = true;
}

bool Context::forward(Component *action)
{
    Q_D(Context);
    return d->dispatcher->forward(this, action);
}

bool Context::forward(const QString &action)
{
    Q_D(Context);
    return d->dispatcher->forward(this, action);
}

Action *Context::getAction(const QString &action, const QString &ns) const
{
    Q_D(const Context);
    return d->dispatcher->getAction(action, ns);
}

QVector<Action *> Context::getActions(const QString &action, const QString &ns) const
{
    Q_D(const Context);
    return d->dispatcher->getActions(action, ns);
}

QVector<Cutelyst::Plugin *> Context::plugins() const
{
    Q_D(const Context);
    return d->plugins;
}

bool Context::execute(Component *code)
{
    Q_D(Context);
    Q_ASSERT_X(code, "Context::execute", "trying to execute a null Cutelyst::Component");

    static int recursion = qEnvironmentVariableIsSet("RECURSION") ? qEnvironmentVariableIntValue("RECURSION") : 1000;
    if (d->stack.size() >= recursion) {
        QString msg = QStringLiteral("Deep recursion detected (stack size %1) calling %2, %3")
                .arg(QString::number(d->stack.size()), code->reverse(), code->name());
        error(msg);
        setState(false);
        return false;
    }

    bool ret;
    d->stack.push(code);

    if (d->stats) {
        const QString statsInfo = d->statsStartExecute(code);

        ret = code->execute(this);

        if (!statsInfo.isEmpty()) {
            d->statsFinishExecute(statsInfo);
        }
    } else {
        ret = code->execute(this);
    }

    d->stack.pop();

    return ret;
}

QLocale Context::locale() const
{
    Q_D(const Context);
    return d->locale;
}

void Context::setLocale(const QLocale &locale)
{
    Q_D(Context);
    d->locale = locale;
}

QVariant Context::config(const QString &key, const QVariant &defaultValue) const
{
    Q_D(const Context);
    return d->app->config(key, defaultValue);
}

QVariantMap Context::config() const
{
    Q_D(const Context);
    return d->app->config();
}

QString Context::translate(const char *context, const char *sourceText, const char *disambiguation, int n) const
{
    Q_D(const Context);
    return d->app->translate(d->locale, context, sourceText, disambiguation, n);
}

QString ContextPrivate::statsStartExecute(Component *code)
{
    QString actionName;
    // Skip internal actions
    if (code->name().startsWith(QLatin1Char('_'))) {
        return actionName;
    }

    actionName = code->reverse();

    if (qobject_cast<Action *>(code)) {
        actionName.prepend(QLatin1Char('/'));
    }

    if (stack.size() > 2) {
        actionName = QLatin1String("-> ") + actionName;
        actionName = actionName.rightJustified(actionName.size() + stack.size() - 2, QLatin1Char(' '));
    }

    stats->profileStart(actionName);

    return actionName;
}

void ContextPrivate::statsFinishExecute(const QString &statsInfo)
{
    stats->profileEnd(statsInfo);
}

#include "moc_context.cpp"
#include "moc_context_p.cpp"
<|endoftext|>


<commit_before>#include "logger.h"

namespace lightstep {
//------------------------------------------------------------------------------
// LogDefault
//------------------------------------------------------------------------------
static void LogDefault(LogLevel log_level,
                       opentracing::string_view message) noexcept try {
  std::ostringstream oss;
  switch (log_level) {
    case LogLevel::debug:
      oss << "Debug: ";
      break;
    case LogLevel::info:
      oss << "Info: ";
      break;
    case LogLevel::warn:
      oss << "Warn: ";
      break;
    case LogLevel::error:
      oss << "Error: ";
      break;
    case LogLevel::off:
      /* This should never be reached. */
      return;
  }
  oss << message << '\n';
  std::cerr << oss.str();
} catch (const std::exception& /*e*/) {
  // Ignore errors.
}

//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
Logger::Logger() : logger_sink_{LogDefault} {}

Logger::Logger(
    std::function<void(LogLevel, opentracing::string_view)>&& logger_sink) {
  if (logger_sink) {
    logger_sink_ = std::move(logger_sink);
  } else {
    logger_sink_ = LogDefault;
  }
}

//------------------------------------------------------------------------------
// Log
//------------------------------------------------------------------------------
void Logger::Log(LogLevel level,
                 opentracing::string_view message) noexcept try {
  if (static_cast<int>(level) >= static_cast<int>(level_)) {
    logger_sink_(level, message);
  }
} catch (const std::exception& /*e*/) {
  // Ignore exceptions.
}
}  // namespace lightstep
<commit_msg>Add missing header.<commit_after>#include "logger.h"
#include <iostream>
#include <sstream>

namespace lightstep {
//------------------------------------------------------------------------------
// LogDefault
//------------------------------------------------------------------------------
static void LogDefault(LogLevel log_level,
                       opentracing::string_view message) noexcept try {
  std::ostringstream oss;
  switch (log_level) {
    case LogLevel::debug:
      oss << "Debug: ";
      break;
    case LogLevel::info:
      oss << "Info: ";
      break;
    case LogLevel::warn:
      oss << "Warn: ";
      break;
    case LogLevel::error:
      oss << "Error: ";
      break;
    case LogLevel::off:
      /* This should never be reached. */
      return;
  }
  oss << message << '\n';
  std::cerr << oss.str();
} catch (const std::exception& /*e*/) {
  // Ignore errors.
}

//------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------
Logger::Logger() : logger_sink_{LogDefault} {}

Logger::Logger(
    std::function<void(LogLevel, opentracing::string_view)>&& logger_sink) {
  if (logger_sink) {
    logger_sink_ = std::move(logger_sink);
  } else {
    logger_sink_ = LogDefault;
  }
}

//------------------------------------------------------------------------------
// Log
//------------------------------------------------------------------------------
void Logger::Log(LogLevel level,
                 opentracing::string_view message) noexcept try {
  if (static_cast<int>(level) >= static_cast<int>(level_)) {
    logger_sink_(level, message);
  }
} catch (const std::exception& /*e*/) {
  // Ignore exceptions.
}
}  // namespace lightstep
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2007 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/feature_factory.hpp>

// ogr
#include "sqlite_featureset.hpp"

using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;
using mapnik::transcoder;
using mapnik::feature_factory;

sqlite_featureset::sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
                                     std::string const& encoding,
                                     mapnik::wkbFormat format,
                                     bool multiple_geometries)
   : rs_(rs),
     tr_(new transcoder(encoding)),
     format_(format),
     multiple_geometries_(multiple_geometries)
{
}

sqlite_featureset::~sqlite_featureset() {}

feature_ptr sqlite_featureset::next()
{
    if (rs_->is_valid () && rs_->step_next ())
    {
        int size;
        const char* data = (const char *) rs_->column_blob (0, size);
        if (!data)
            return feature_ptr();
        int feature_id = rs_->column_integer (1);

#ifdef MAPNIK_DEBUG
        // std::clog << "Sqlite Plugin: feature_oid=" << feature_id << std::endl;
#endif

        feature_ptr feature(feature_factory::create(feature_id));
        geometry_utils::from_wkb(*feature,data,size,multiple_geometries_,format_);

        for (int i = 2; i < rs_->column_count (); ++i)
        {
           const int type_oid = rs_->column_type (i);
           const char* fld_name = rs_->column_name (i);

           switch (type_oid)
           {
              case SQLITE_INTEGER:
              {
                 boost::put(*feature,fld_name,rs_->column_integer (i));
                 break;
              }

              case SQLITE_FLOAT:
              {
                 boost::put(*feature,fld_name,rs_->column_double (i));
                 break;
              }

              case SQLITE_TEXT:
              {
                 UnicodeString ustr = tr_->transcode (rs_->column_text (i));
                 boost::put(*feature,fld_name,ustr);
                 break;
              }

              case SQLITE_NULL:
              {
                 boost::put(*feature,fld_name,mapnik::value_null());
                 break;
              }

              case SQLITE_BLOB:
                 break;

              default:
#ifdef MAPNIK_DEBUG
                 std::clog << "Sqlite Plugin: unhandled type_oid=" << type_oid << std::endl;
#endif
                 break;
           }
        }

        return feature;
    }

    return feature_ptr();
}

<commit_msg>sqlite: unquote fields to avoid filter failures - preliminary fix for #822<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2007 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// mapnik
#include <mapnik/global.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/wkb.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/sql_utils.hpp>

// ogr
#include "sqlite_featureset.hpp"

using mapnik::query;
using mapnik::box2d;
using mapnik::CoordTransform;
using mapnik::Feature;
using mapnik::feature_ptr;
using mapnik::geometry_utils;
using mapnik::transcoder;
using mapnik::feature_factory;

sqlite_featureset::sqlite_featureset(boost::shared_ptr<sqlite_resultset> rs,
                                     std::string const& encoding,
                                     mapnik::wkbFormat format,
                                     bool multiple_geometries)
   : rs_(rs),
     tr_(new transcoder(encoding)),
     format_(format),
     multiple_geometries_(multiple_geometries)
{
}

sqlite_featureset::~sqlite_featureset() {}

feature_ptr sqlite_featureset::next()
{
    if (rs_->is_valid () && rs_->step_next ())
    {
        int size;
        const char* data = (const char *) rs_->column_blob (0, size);
        if (!data)
            return feature_ptr();
        int feature_id = rs_->column_integer (1);

#ifdef MAPNIK_DEBUG
        // std::clog << "Sqlite Plugin: feature_oid=" << feature_id << std::endl;
#endif

        feature_ptr feature(feature_factory::create(feature_id));
        geometry_utils::from_wkb(*feature,data,size,multiple_geometries_,format_);

        for (int i = 2; i < rs_->column_count (); ++i)
        {
           const int type_oid = rs_->column_type (i);
           // TODO - avoid copying string
           // TODO - handle single quotes
           const char* fld_name = mapnik::unquote_sql(rs_->column_name(i)).c_str();

           switch (type_oid)
           {
              case SQLITE_INTEGER:
              {
                 boost::put(*feature,fld_name,rs_->column_integer (i));
                 break;
              }

              case SQLITE_FLOAT:
              {
                 boost::put(*feature,fld_name,rs_->column_double (i));
                 break;
              }

              case SQLITE_TEXT:
              {
                 UnicodeString ustr = tr_->transcode (rs_->column_text (i));
                 boost::put(*feature,fld_name,ustr);
                 break;
              }

              case SQLITE_NULL:
              {
                 boost::put(*feature,fld_name,mapnik::value_null());
                 break;
              }

              case SQLITE_BLOB:
                 break;

              default:
#ifdef MAPNIK_DEBUG
                 std::clog << "Sqlite Plugin: unhandled type_oid=" << type_oid << std::endl;
#endif
                 break;
           }
        }

        return feature;
    }

    return feature_ptr();
}

<|endoftext|>


<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    uiserver/uiserver_win.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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 of the License, or
    (at your option) any later version.

    Kleopatra 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.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "uiserver_p.h"

#include "utils/gnupg-registry.h"

#include <QFile>
#include <QDir>
#include <QTextStream>
#include <qendian.h>

#include <stdexcept>
#include <cassert>

#include <windows.h>
#include <io.h>
#include <winsock2.h>

#include <cstring>
#include <cstdlib>

using namespace Kleo;
using namespace boost;

QString UiServer::Private::makeFileName( const QString & socket ) const {
    if ( !socket.isEmpty() )
        return socket;
    if ( tmpDir.status() != 0 )
        throw_<std::runtime_error>( tr( "Couldn't create directory %1: %2" ).arg( tmpDirPrefix() + "XXXXXXXX", QString::fromLocal8Bit( strerror(errno) ) ) );
    const char * const gnupg_home = default_homedir();
    const QDir dir( gnupg_home ? QFile::decodeName( gnupg_home ) : tmpDir.name() );
    assert( dir.exists() );
    return dir.absoluteFilePath( "S.uiserver" );
}

// ### MERGE THE FOLLOWING WITH uiserver_unix.cpp

static inline QString system_error_string() {
    return QString::fromLocal8Bit( strerror(errno) );
}

void UiServer::Private::makeListeningSocket() {

    // First, create a file (we do this only for the name, gmpfh)
    const QString fileName = socketname;
    if ( QFile::exists( fileName ) )
        throw_<std::runtime_error>( tr( "Detected another running gnupg UI server listening at %1." ).arg( fileName ) );
    const QByteArray encodedFileName = QFile::encodeName( fileName );

    // Create a Unix Domain Socket:
    const assuan_fd_t sock = assuan_sock_new( AF_UNIX, SOCK_STREAM, 0 );
    if ( sock == ASSUAN_INVALID_FD )
        throw_<std::runtime_error>( tr( "Couldn't create socket: %1" ).arg( system_error_string() ) );

    try {
        // Bind
        struct sockaddr_un sa;
        std::memset( &sa, 0, sizeof(sa) );
        sa.sun_family = AF_UNIX;
        std::strncpy( sa.sun_path, encodedFileName.constData(), sizeof( sa.sun_path ) - 1 );
        if ( assuan_sock_bind( sock, (struct sockaddr*)&sa, sizeof( sa ) ) )
            throw_<std::runtime_error>( tr( "Couldn't bind to socket: %1" ).arg( system_error_string() ) );

        if ( assuan_sock_get_nonce( (struct sockaddr*)&sa, sizeof( sa ), &nonce ) )
            throw_<std::runtime_error>( tr("Couldn't get socket nonce: %1" ).arg( system_error_string() ) );

        // Listen
        if ( ::listen( sock, SOMAXCONN ) )
            throw_<std::runtime_error>( tr( "Couldn't listen to socket: %1" ).arg( system_error_string() ) );

        if ( !setSocketDescriptor( sock ) )
            throw_<std::runtime_error>( tr( "Couldn't pass socket to Qt: %1. This should not happen, please report this bug." ).arg( errorString() ) );

    } catch ( ... ) {
        assuan_sock_close( sock );
        throw;
    }

}
<commit_msg>compile on windows<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    uiserver/uiserver_win.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra 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 of the License, or
    (at your option) any later version.

    Kleopatra 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.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include <config-kleopatra.h>

#include "uiserver_p.h"

#include "utils/gnupg-registry.h"

#include <QFile>
#include <QDir>
#include <QTextStream>
#include <qendian.h>

#include <stdexcept>
#include <cassert>

#include <windows.h>
#include <io.h>
#include <winsock2.h>

#include <cstring>
#include <cstdlib>

using namespace Kleo;
using namespace boost;

QString UiServer::Private::makeFileName( const QString & socket ) const {
    if ( !socket.isEmpty() )
        return socket;
    if ( tmpDir.status() != 0 )
        throw_<std::runtime_error>( tr( "Couldn't create directory %1: %2" ).arg( tmpDirPrefix() + "XXXXXXXX", QString::fromLocal8Bit( strerror(errno) ) ) );
    const char * const gnupg_home = default_homedir();
    const QDir dir( gnupg_home ? QFile::decodeName( gnupg_home ) : tmpDir.name() );
    assert( dir.exists() );
    return dir.absoluteFilePath( "S.uiserver" );
}

// ### MERGE THE FOLLOWING WITH uiserver_unix.cpp

static inline QString system_error_string() {
    return QString::fromLocal8Bit( strerror(errno) );
}

void UiServer::Private::makeListeningSocket() {

    // First, create a file (we do this only for the name, gmpfh)
    const QString fileName = socketname;
    if ( QFile::exists( fileName ) )
        throw_<std::runtime_error>( tr( "Detected another running gnupg UI server listening at %1." ).arg( fileName ) );
    const QByteArray encodedFileName = QFile::encodeName( fileName );

    // Create a Unix Domain Socket:
    const assuan_fd_t sock = assuan_sock_new( AF_UNIX, SOCK_STREAM, 0 );
    if ( sock == ASSUAN_INVALID_FD )
        throw_<std::runtime_error>( tr( "Couldn't create socket: %1" ).arg( system_error_string() ) );

    try {
        // Bind
        struct sockaddr_un sa;
        std::memset( &sa, 0, sizeof(sa) );
        sa.sun_family = AF_UNIX;
        std::strncpy( sa.sun_path, encodedFileName.constData(), sizeof( sa.sun_path ) - 1 );
        if ( assuan_sock_bind( sock, (struct sockaddr*)&sa, sizeof( sa ) ) )
            throw_<std::runtime_error>( tr( "Couldn't bind to socket: %1" ).arg( system_error_string() ) );

        if ( assuan_sock_get_nonce( (struct sockaddr*)&sa, sizeof( sa ), &nonce ) )
            throw_<std::runtime_error>( tr("Couldn't get socket nonce: %1" ).arg( system_error_string() ) );

        // Listen
        if ( ::listen( (SOCKET)sock, SOMAXCONN ) )
            throw_<std::runtime_error>( tr( "Couldn't listen to socket: %1" ).arg( system_error_string() ) );

        if ( !setSocketDescriptor( (int)sock  ) )
            throw_<std::runtime_error>( tr( "Couldn't pass socket to Qt: %1. This should not happen, please report this bug." ).arg( errorString() ) );

    } catch ( ... ) {
        assuan_sock_close( sock );
        throw;
    }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: sfxhelp.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: mba $ $Date: 2001-06-18 09:48:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SFX_HELP_HXX
#define _SFX_HELP_HXX

#ifndef _HELP_HXX //autogen
#include <vcl/help.hxx>
#endif

#include <tools/string.hxx>

class SfxHelpDB_Impl;
class SfxFrame;
class SfxHelp : public Help
{
    String          aTicket;        // for Plugins
    String          aUser;
    String          aLanguageStr;
    String          aCountryStr;
    sal_Bool        bIsDebug;
    SfxHelpDB_Impl* pDB;

private:
    virtual BOOL    Start( ULONG nHelpId, const Window* pWindow );
    virtual BOOL    Start( const String& rURL, const Window* pWindow );
    String          GetHelpModuleName( ULONG nHelpId );

public:
                    SfxHelp();
                    ~SfxHelp();
    void            SetTicket( const String& rTicket )
                    { aTicket = rTicket;}
    void            SetUser( const String& rUser )
                    { aUser = rUser;}

    virtual XubString   GetHelpText( ULONG nHelpId, const Window* pWindow );
    void            OpenHelpAgent( SfxFrame* pFrame, sal_Int32 nHelpId );
    String          CreateHelpURL( sal_Int32 nHelpId, const String& rModuleName );
};

#endif // #ifndef _SFX_HELP_HXX

<commit_msg>fix: #88353# helpid has to be ULONG<commit_after>/*************************************************************************
 *
 *  $RCSfile: sfxhelp.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: pb $ $Date: 2001-06-18 11:49:56 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _SFX_HELP_HXX
#define _SFX_HELP_HXX

#ifndef _HELP_HXX //autogen
#include <vcl/help.hxx>
#endif

#include <tools/string.hxx>

class SfxHelpDB_Impl;
class SfxFrame;
class SfxHelp : public Help
{
    String          aTicket;        // for Plugins
    String          aUser;
    String          aLanguageStr;
    String          aCountryStr;
    sal_Bool        bIsDebug;
    SfxHelpDB_Impl* pDB;

private:
    virtual BOOL    Start( ULONG nHelpId, const Window* pWindow );
    virtual BOOL    Start( const String& rURL, const Window* pWindow );
    String          GetHelpModuleName( ULONG nHelpId );

public:
                    SfxHelp();
                    ~SfxHelp();
    void            SetTicket( const String& rTicket )
                    { aTicket = rTicket;}
    void            SetUser( const String& rUser )
                    { aUser = rUser;}

    virtual XubString   GetHelpText( ULONG nHelpId, const Window* pWindow );
    void            OpenHelpAgent( SfxFrame* pFrame, sal_Int32 nHelpId );
    String          CreateHelpURL( ULONG nHelpId, const String& rModuleName );
};

#endif // #ifndef _SFX_HELP_HXX

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <set>

#include <boost/test/unit_test.hpp>

#include <seastar/core/thread.hh>

#include "sstables/sstables.hh"
#include "compress.hh"
#include "schema_builder.hh"
#include "tests/test-utils.hh"
#include "sstable_test.hh"

using namespace sstables;

class sstable_assertions final {
    shared_sstable _sst;
public:
    sstable_assertions(schema_ptr schema, const sstring& path, int generation = 1)
        : _sst(make_sstable(std::move(schema),
                            path,
                            generation,
                            sstable_version_types::mc,
                            sstable_format_types::big))
    { }
    void read_toc() {
        _sst->read_toc().get();
    }
    void read_summary() {
        _sst->read_summary(default_priority_class()).get();
    }
    void read_filter() {
        _sst->read_filter(default_priority_class()).get();
    }
    void read_statistics() {
        _sst->read_statistics(default_priority_class()).get();
    }
    void load() {
        _sst->load().get();
    }
    future<index_list> read_index() {
        load();
        return sstables::test(_sst).read_indexes();
    }
    void assert_toc(const std::set<component_type>& expected_components) {
        for (auto& expected : expected_components) {
            if(_sst->_recognized_components.count(expected) == 0) {
                BOOST_FAIL(sprint("Expected component of TOC missing: %s\n ... in: %s",
                                  expected,
                                  std::set<component_type>(
                                      cbegin(_sst->_recognized_components),
                                      cend(_sst->_recognized_components))));
            }
        }
        for (auto& present : _sst->_recognized_components) {
            if (expected_components.count(present) == 0) {
                BOOST_FAIL(sprint("Unexpected component of TOC: %s\n ... when expecting: %s",
                                  present,
                                  expected_components));
            }
        }
    }
};

// Following tests run on files in tests/sstables/3.x/uncompressed/partition_key_only
// They were created using following CQL statements:
//
// CREATE KEYSPACE test_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
//
// CREATE TABLE test_ks.test_table ( pk INT, PRIMARY KEY(pk))
//      WITH compression = { 'enabled' : false };
//
// INSERT INTO test_ks.test_table(pk) VALUES(1);
// INSERT INTO test_ks.test_table(pk) VALUES(2);
// INSERT INTO test_ks.test_table(pk) VALUES(3);
// INSERT INTO test_ks.test_table(pk) VALUES(4);
// INSERT INTO test_ks.test_table(pk) VALUES(5);

static thread_local const sstring UNCOMPRESSED_PARTITION_KEY_ONLY_PATH =
    "tests/sstables/3.x/uncompressed/partition_key_only";
static thread_local const schema_ptr UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA =
    schema_builder("test_ks", "test_table")
        .with_column("pk", int32_type, column_kind::partition_key)
        .build();

SEASTAR_TEST_CASE(test_uncompressed_partition_key_only_load) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA, UNCOMPRESSED_PARTITION_KEY_ONLY_PATH);
        sst.load();
    });
}

// Following tests run on files in tests/sstables/3.x/uncompressed/simple
// They were created using following CQL statements:
//
// CREATE KEYSPACE test_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
//
// CREATE TABLE test_ks.test_table ( pk INT, ck INT, val INT, PRIMARY KEY(pk, ck))
//      WITH compression = { 'enabled' : false };
//
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(1, 101, 1001);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(2, 102, 1002);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(3, 103, 1003);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(4, 104, 1004);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(5, 105, 1005);

static thread_local const sstring UNCOMPRESSED_SIMPLE_PATH = "tests/sstables/3.x/uncompressed/simple";
static thread_local const schema_ptr UNCOMPRESSED_SIMPLE_SCHEMA =
    schema_builder("test_ks", "test_table")
        .with_column("pk", int32_type, column_kind::partition_key)
        .with_column("ck", int32_type, column_kind::clustering_key)
        .with_column("val", int32_type)
        .build();

SEASTAR_TEST_CASE(test_uncompressed_simple_read_toc) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        using ct = component_type;
        sst.assert_toc({ct::Index,
                        ct::Data,
                        ct::TOC,
                        ct::Summary,
                        ct::Digest,
                        ct::CRC,
                        ct::Filter,
                        ct::Statistics});
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_summary) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_summary();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_filter) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_filter();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_statistics) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_statistics();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_load) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.load();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_index) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        auto vec = sst.read_index().get0();
        BOOST_REQUIRE_EQUAL(1, vec.size());
    });
}
<commit_msg>Test for reading sstable in MC format with no columns<commit_after>/*
 * Copyright (C) 2018 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <set>

#include <boost/test/unit_test.hpp>

#include <seastar/core/thread.hh>

#include "sstables/sstables.hh"
#include "compress.hh"
#include "schema_builder.hh"
#include "tests/test-utils.hh"
#include "sstable_test.hh"
#include "flat_mutation_reader_assertions.hh"

using namespace sstables;

class sstable_assertions final {
    shared_sstable _sst;
public:
    sstable_assertions(schema_ptr schema, const sstring& path, int generation = 1)
        : _sst(make_sstable(std::move(schema),
                            path,
                            generation,
                            sstable_version_types::mc,
                            sstable_format_types::big,
                            gc_clock::now(),
                            default_io_error_handler_gen(),
                            1))
    { }
    void read_toc() {
        _sst->read_toc().get();
    }
    void read_summary() {
        _sst->read_summary(default_priority_class()).get();
    }
    void read_filter() {
        _sst->read_filter(default_priority_class()).get();
    }
    void read_statistics() {
        _sst->read_statistics(default_priority_class()).get();
    }
    void load() {
        _sst->load().get();
    }
    future<index_list> read_index() {
        load();
        return sstables::test(_sst).read_indexes();
    }
    flat_mutation_reader read_rows_flat() {
        return _sst->read_rows_flat(_sst->_schema);
    }
    void assert_toc(const std::set<component_type>& expected_components) {
        for (auto& expected : expected_components) {
            if(_sst->_recognized_components.count(expected) == 0) {
                BOOST_FAIL(sprint("Expected component of TOC missing: %s\n ... in: %s",
                                  expected,
                                  std::set<component_type>(
                                      cbegin(_sst->_recognized_components),
                                      cend(_sst->_recognized_components))));
            }
        }
        for (auto& present : _sst->_recognized_components) {
            if (expected_components.count(present) == 0) {
                BOOST_FAIL(sprint("Unexpected component of TOC: %s\n ... when expecting: %s",
                                  present,
                                  expected_components));
            }
        }
    }
};

// Following tests run on files in tests/sstables/3.x/uncompressed/partition_key_only
// They were created using following CQL statements:
//
// CREATE KEYSPACE test_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
//
// CREATE TABLE test_ks.test_table ( pk INT, PRIMARY KEY(pk))
//      WITH compression = { 'enabled' : false };
//
// INSERT INTO test_ks.test_table(pk) VALUES(1);
// INSERT INTO test_ks.test_table(pk) VALUES(2);
// INSERT INTO test_ks.test_table(pk) VALUES(3);
// INSERT INTO test_ks.test_table(pk) VALUES(4);
// INSERT INTO test_ks.test_table(pk) VALUES(5);

static thread_local const sstring UNCOMPRESSED_PARTITION_KEY_ONLY_PATH =
    "tests/sstables/3.x/uncompressed/partition_key_only";
static thread_local const schema_ptr UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA =
    schema_builder("test_ks", "test_table")
        .with_column("pk", int32_type, column_kind::partition_key)
        .build();

SEASTAR_TEST_CASE(test_uncompressed_partition_key_only_load) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA, UNCOMPRESSED_PARTITION_KEY_ONLY_PATH);
        sst.load();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_partition_key_only_read) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA, UNCOMPRESSED_PARTITION_KEY_ONLY_PATH);
        sst.load();
        auto to_key = [] (int key) {
            auto bytes = int32_type->decompose(int32_t(key));
            auto pk = partition_key::from_single_value(*UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA, bytes);
            return dht::global_partitioner().decorate_key(*UNCOMPRESSED_PARTITION_KEY_ONLY_SCHEMA, pk);
        };
        assert_that(sst.read_rows_flat())
            .produces_partition_start(to_key(5))
            .produces_partition_end()
            .produces_partition_start(to_key(1))
            .produces_partition_end()
            .produces_partition_start(to_key(2))
            .produces_partition_end()
            .produces_partition_start(to_key(4))
            .produces_partition_end()
            .produces_partition_start(to_key(3))
            .produces_partition_end()
            .produces_end_of_stream();
    });
}

// Following tests run on files in tests/sstables/3.x/uncompressed/simple
// They were created using following CQL statements:
//
// CREATE KEYSPACE test_ks WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
//
// CREATE TABLE test_ks.test_table ( pk INT, ck INT, val INT, PRIMARY KEY(pk, ck))
//      WITH compression = { 'enabled' : false };
//
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(1, 101, 1001);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(2, 102, 1002);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(3, 103, 1003);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(4, 104, 1004);
// INSERT INTO test_ks.test_table(pk, ck, val) VALUES(5, 105, 1005);

static thread_local const sstring UNCOMPRESSED_SIMPLE_PATH = "tests/sstables/3.x/uncompressed/simple";
static thread_local const schema_ptr UNCOMPRESSED_SIMPLE_SCHEMA =
    schema_builder("test_ks", "test_table")
        .with_column("pk", int32_type, column_kind::partition_key)
        .with_column("ck", int32_type, column_kind::clustering_key)
        .with_column("val", int32_type)
        .build();

SEASTAR_TEST_CASE(test_uncompressed_simple_read_toc) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        using ct = component_type;
        sst.assert_toc({ct::Index,
                        ct::Data,
                        ct::TOC,
                        ct::Summary,
                        ct::Digest,
                        ct::CRC,
                        ct::Filter,
                        ct::Statistics});
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_summary) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_summary();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_filter) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_filter();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_statistics) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.read_toc();
        sst.read_statistics();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_load) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        sst.load();
    });
}

SEASTAR_TEST_CASE(test_uncompressed_simple_read_index) {
    return seastar::async([] {
        sstable_assertions sst(UNCOMPRESSED_SIMPLE_SCHEMA, UNCOMPRESSED_SIMPLE_PATH);
        auto vec = sst.read_index().get0();
        BOOST_REQUIRE_EQUAL(1, vec.size());
    });
}
<|endoftext|>