/* * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2.0, as * published by the Free Software Foundation. * * This program is also distributed with certain software (including * but not limited to OpenSSL) that is licensed under separate terms, * as designated in a particular file or component or in included license * documentation. The authors of MySQL hereby grant you an * additional permission to link the program and your derivative works * with the separately licensed software that they have included with * MySQL. * * Without limiting anything contained in the foregoing, this file, * which is part of MySQL Connector/C++, is also subject to the * Universal FOSS Exception, version 1.0, a copy of which can be found at * http://oss.oracle.com/licenses/universal-foss-exception. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License, version 2.0, 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 St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MYSQLX_COMMON_OP_IF_H #define MYSQLX_COMMON_OP_IF_H /* This file defines a hierarchy of abstract interfaces for objects that represent database operations. The base interface is the Executable_if for any operation that can be executed. Other interfaces in the hierarchy allow specifying more details of the operation. Note: Header op_impl.h defines implementations of these interfaces used in the connector. */ #include "../common_constants.h" #include namespace mysqlx { namespace common { class Value; #define LOCK_MODE(X,N) X = N, enum Lock_mode { LOCK_MODE_LIST(LOCK_MODE) }; #define LOCK_CONTENTION(X,N) X = N, enum class Lock_contention { LOCK_CONTENTION_LIST(LOCK_CONTENTION) }; class Result_init; /* Abstract interface for internal implementations of an executable object. The execute() method returns a Result_init object which can be used to construct a result instance. Implementation of an executable object holds a description of the operation that should be executed. Executable objects can be copied (for example by copy assignment operation) and in this case a new copy of the current description of the operation should be created by clone() method. After cloning, the 2 executable implementations can be modified and executed independently. See various Op_xxx classes defined for example in operation.h to see examples of executable object implementations. Note that these Op_xxx classes do not directly inherit from Executable_if. Instead they use a whole hierarchy of implementation classes based on Executable_if. But in the end, each implementation of an executable object defines the execute() method that executes given operation using all the information collected using other methods of the implementation class. */ struct Executable_if { /* Execute the operation and return reference to object which implements Result_init interface. Such object is then used to construct a result instance. */ virtual Result_init& execute() = 0; virtual Executable_if *clone() const = 0; virtual ~Executable_if() {} }; /* The XXX_if classes defined below form a hierarchy of interfaces, based on Executable_if, for internal implementations of various crud operations. The concrete implementations, like Op_collection_find defined in operation.h, implements one of the top interfaces in this hierarchy but the hierarchy allows casting the implementation down to the layer implementing particular aspect of the operation. For example Limit_if interface allows setting limit and offset for returned/affected rows/documents, which is common for different CRUD operations. */ struct Bind_if : public Executable_if { using string = std::wstring; using Value = mysqlx::common::Value; // Add value for named parameter virtual void add_param(const string&, const Value&) = 0; // Add value for positional parameter virtual void add_param(Value) = 0; virtual void clear_params() = 0; }; struct Limit_if : public Bind_if { virtual void set_offset(unsigned) = 0; virtual void clear_offset() = 0; virtual void set_limit(unsigned) = 0; virtual void clear_limit() = 0; }; struct Sort_if : public Limit_if { using string = std::wstring; enum direction_t { ASC, DESC }; virtual void add_sort(const string &expr, direction_t dir) = 0; virtual void add_sort(const string&) = 0; virtual void clear_sort() = 0; }; struct Having_if : public Sort_if { using string = std::wstring; virtual void set_having(const string&) = 0; virtual void clear_having() = 0; }; struct Group_by_if : public Having_if { using string = std::wstring; virtual void add_group_by(const string&) = 0; virtual void clear_group_by() = 0; }; struct Proj_if : public Group_by_if { using string = std::wstring; /* Add projection specification for a table query. It is an expression with optional "AS " suffix. */ virtual void add_proj(const string&) = 0; /* Set projection for a document query. It is a JSON-like string but document field values are interpreted as expressions. */ virtual void set_proj(const string&) = 0; virtual void clear_proj() = 0; }; template struct Select_if : public Base { using string = std::wstring; using Lock_mode = mysqlx::common::Lock_mode; // Set expression to select rows/documents. virtual void set_where(const string&) = 0; // Define lock mode for rows/documents returned by the query. virtual void set_lock_mode(Lock_mode, Lock_contention) = 0; virtual void clear_lock_mode() = 0; }; // -------------------------------------------------------------------------- struct Collection_find_if : public Select_if {}; /* Interface to internal implementations of CRUD add operation. */ struct Collection_add_if : public Executable_if { /* Note: Current implementation only supports sending documents in form of UTF8 JSON strings. */ virtual void add_json(const std::string&) = 0; virtual void clear_docs() = 0; }; struct Collection_remove_if : public Select_if {}; /* Interface to internal implementations of CRUD modify operation. Methods `add_operation` are used to pass to the implementation object the modifications requested by the user. */ struct Collection_modify_if : public Select_if { using string = std::wstring; using Value = mysqlx::common::Value; enum Operation { SET, UNSET, ARRAY_INSERT, ARRAY_APPEND, ARRAY_DELETE, MERGE_PATCH }; virtual void add_operation(Operation, const string&, const Value&) = 0; virtual void add_operation(Operation, const string&) = 0; virtual void clear_modifications() = 0; }; // -------------------------------------------------------------------------- /* Interface to be implemented by internal implementations of table insert operation. */ template struct Table_insert_if : public Executable_if { using string = std::wstring; /* Pass to the implementation names of columns specified by the user. Columns are passed one-by-one in the order in which they were specified. */ virtual void add_column(const string&) = 0; virtual void clear_columns() = 0; /* Pass to the implementation a row that should be inserted into the table. Several rows can be passed. TODO: use move semantics instead */ virtual void add_row(const Row_impl&) = 0; virtual void clear_rows() = 0; }; /* Interface to be implemented by internal implementations of table CRUD select operation. Method `add_where` is used to report selection criteria to the implementation. */ struct Table_select_if : public Select_if {}; /* Interface to be implemented by internal implementations of table CRUD remove operation. Selection criteria which selects rows to be removed is passed to the implementation using `set_where` method. Note: setting where condition to empty string removes it. */ struct Table_remove_if : public Select_if {}; /* Interface to be implemented by internal implementations of table CRUD update operation. Such update operation sets values of fields in a row. Name of the column that should be set and expression defining new value are reported to the implementation using method `add_set`. */ struct Table_update_if : public Table_remove_if { using string = std::wstring; using Value = mysqlx::common::Value; virtual void add_set(const string&, const Value&) = 0; virtual void clear_modifications() = 0; }; } // internal } // mysqlx #endif