MySQL Connector/C++
MySQL connector library for C and C++ applications
crud.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, 2023, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0, as
6 * published by the Free Software Foundation.
7 *
8 * This program is also distributed with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an
12 * additional permission to link the program and your derivative works
13 * with the separately licensed software that they have included with
14 * MySQL.
15 *
16 * Without limiting anything contained in the foregoing, this file,
17 * which is part of MySQL Connector/C++, is also subject to the
18 * Universal FOSS Exception, version 1.0, a copy of which can be found at
19 * http://oss.oracle.com/licenses/universal-foss-exception.
20 *
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 * See the GNU General Public License, version 2.0, for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef MYSQLX_CRUD_H
32#define MYSQLX_CRUD_H
33
40#include "common.h"
41#include "detail/crud.h"
42
43
44namespace mysqlx {
45MYSQLX_ABI_BEGIN(2,0)
46
47class Session;
48class Collection;
49class Table;
50
51namespace internal {
52
53/*
54 Factory for constructing concrete implementations of various CRUD
55 operations. All these implementations implement the base Executable_if
56 interface.
57
58 Note: The caller of mk_xxx() method takes ownership of the returned
59 implementation object.
60*/
61
62struct PUBLIC_API Crud_factory
63{
64 using Impl = common::Executable_if;
65
66 static Impl* mk_add(Collection &coll);
67 static Impl* mk_remove(Collection &coll, const string &expr);
68 static Impl* mk_find(Collection &coll);
69 static Impl* mk_find(Collection &coll, const string &expr);
70 static Impl* mk_modify(Collection &coll, const string &expr);
71
72 static Impl* mk_insert(Table &tbl);
73 static Impl* mk_select(Table &tbl);
74 static Impl* mk_update(Table &tbl);
75 static Impl* mk_remove(Table &tbl);
76
77 static Impl* mk_sql(Session &sess, const string &sql);
78};
79
80
81} // internal
82
83
84/*
85 Different CRUD operation classes derive from `Executable` which defines
86 the `execute()` method that executes given operation. Derived classes
87 define additional methods that can modify the operation before it gets
88 executed.
89
90 The hierarchy of classes reflects the grammar that defines the order in which
91 fluent API calls can be done. It is built using templates, such as Offset<>
92 below, which add one API call on top of base class which defines remaining
93 API calls that can be called later. For example, type
94
95 Limit< Offset< Executable<...> > >
96
97 represents an operation for which first .limit() can be called, followed by
98 .offset() and then finally .execute(). See classes like
99 Collection_find_base in collection_crud.h for more examples.
100
101 Each template assumes that its base class defines method 'get_impl()' which
102 returns a pointer to the internal implementation object. It also assumes that
103 this implementation is of appropriate type and can be casted to
104 the appropriate interface type. For example Limit<> template assumes
105 that the implementation type can be casted to Limit_if type.
106*/
107
108
117{
118#define DEVAPI_LOCK_CONTENTION_ENUM(X,N) X = N,
119
120 LOCK_CONTENTION_LIST(DEVAPI_LOCK_CONTENTION_ENUM)
121};
122
123namespace internal {
124
129template <class Base>
130class Offset
131 : public Base
132{
133 using Operation = Base;
134
135public:
136
142 Operation& offset(unsigned rows)
143 {
144 try {
145 get_impl()->set_offset(rows);
146 return *this;
147 }
148 CATCH_AND_WRAP
149 }
150
151protected:
152
153 using Impl = common::Limit_if;
154
155 Impl* get_impl()
156 {
157 return static_cast<Impl*>(Base::get_impl());
158 }
159};
160
161
163
164template <class Base>
165class Limit
166 : public Base
167{
168 using Operation = Base;
169
170public:
171
176 Operation& limit(unsigned items)
177 {
178 try {
179 get_impl()->set_limit(items);
180 return *this;
181 }
182 CATCH_AND_WRAP
183 }
184
185protected:
186
187 using Impl = common::Limit_if;
188
189 Impl* get_impl()
190 {
191 return static_cast<Impl*>(Base::get_impl());
192 }
193};
194
195
197
198template <class Base>
199class Sort
200 : public Base
201 , Sort_detail
202{
203 using Operation = Base;
204
205public:
206
215 template <typename...Type>
216 Operation& sort(Type... spec)
217 {
218 try {
219 get_impl()->clear_sort();
220 add_sort(get_impl(), spec...);
221 return *this;
222 }
223 CATCH_AND_WRAP
224 }
225
226protected:
227
228 using Impl = common::Sort_if;
229
230 Impl* get_impl()
231 {
232 return static_cast<Impl*>(Base::get_impl());
233 }
234};
235
236
238
239template <class Base>
240class Order_by
241 : public Base
242 , Sort_detail
243{
244 using Operation = Base;
245
246public:
247
256 template <typename...Type>
257 Operation& orderBy(Type... spec)
258 {
259 try {
260 get_impl()->clear_sort();
261 add_sort(get_impl(), spec...);
262 return *this;
263 }
264 CATCH_AND_WRAP
265 }
266
267protected:
268
269 using Impl = common::Sort_if;
270
271 Impl* get_impl()
272 {
273 return static_cast<Impl*>(Base::get_impl());
274 }
275};
276
277
279
280template <class Base>
281class Having
282 : public Base
283{
284 using Operation = Base;
285
286public:
287
294 Operation& having(const string& having_spec)
295 {
296 try {
297 get_impl()->set_having(having_spec);
298 return *this;
299 }
300 CATCH_AND_WRAP
301 }
302
303protected:
304
305 using Impl = common::Having_if;
306
307 Impl* get_impl()
308 {
309 return static_cast<Impl*>(Base::get_impl());
310 }
311};
312
313
315
316template <class Base>
317class Group_by
318 : public Base
319 , Group_by_detail
320{
321 using Operation = Base;
322
323public:
324
332 template <typename... Expr>
333 Operation& groupBy(Expr... group_by_spec)
334 {
335 try {
336 get_impl()->clear_group_by();
337 do_group_by(get_impl(), group_by_spec...);
338 return *this;
339 }
340 CATCH_AND_WRAP
341 }
342
343protected:
344
345 using Impl = common::Group_by_if;
346
347 Impl* get_impl()
348 {
349 return static_cast<Impl*>(Base::get_impl());
350 }
351};
352
353
355
356template <class Base>
358 : public Base
359 , Bind_detail
360{
362
363public:
364
372 template <typename... Types>
373 BindOperation& bind(Types&&... vals)
374 {
375 try {
376 add_params(get_impl(), std::forward<Types>(vals)...);
377 return *this;
378 }
379 CATCH_AND_WRAP
380 }
381
382protected:
383
384 using Impl = common::Bind_if;
385
386 Impl* get_impl()
387 {
388 return static_cast<Impl*>(Base::get_impl());
389 }
390};
391
392
394
395template <class Base>
396class Bind_parameters
397 : public Base
398{
400 using Operation = Base;
401
402public:
403
411 BindOperation& bind(const string &parameter, const Value &val)
412 {
413 //TODO: Protocol supports Document and Array... but common::Values doesn't!
414 if (Value::DOCUMENT == val.getType())
415 throw_error("Can not bind a parameter to a document");
416
417 if (Value::ARRAY == val.getType())
418 throw_error("Can not bind a parameter to an array");
419
420 try {
421 get_impl()->add_param(parameter, (const common::Value&)val);
422 return *this;
423 }
424 CATCH_AND_WRAP
425 }
426
432 template <class Map>
433 Operation& bind(const Map &args)
434 {
435 for (const auto &keyval : args)
436 {
437 bind(keyval.first, keyval.second);
438 }
439 return *this;
440 }
441
442protected:
443
444 using Impl = common::Bind_if;
445
446 Impl* get_impl()
447 {
448 return static_cast<Impl*>(Base::get_impl());
449 }
450};
451
452
454
455template <class Base, class IMPL>
456class Set_lock
457 : public Base
458{
459 using Operation = Base;
460
461public:
462
469 Operation&
470 lockShared(LockContention contention= LockContention::DEFAULT)
471 {
472 get_impl()->set_lock_mode(common::Lock_mode::SHARED,
473 common::Lock_contention((unsigned)contention));
474 return *this;
475 }
476
485 Operation&
486 lockExclusive(LockContention contention = LockContention::DEFAULT)
487 {
488 get_impl()->set_lock_mode(common::Lock_mode::EXCLUSIVE,
489 common::Lock_contention((unsigned)contention));
490 return *this;
491 }
492
493protected:
494
495 using Impl = IMPL;
496
497 Impl* get_impl()
498 {
499 return static_cast<Impl*>(Base::get_impl());
500 }
501};
502
503
504} // internal
505MYSQLX_ABI_END(2,0)
506} // mysqlx
507
508#endif
Value object can store value of scalar type, string, array or document.
Definition: document.h:230
Type getType() const
Return type of the value stored in this instance (or VNULL if no value is stored).
Definition: document.h:656
Template for defining fluent api for CRUD operations.
Definition: crud.h:397
Template for defining fluent api for CRUD operations.
Definition: crud.h:359
Template for defining fluent api for CRUD operations.
Definition: crud.h:319
Template for defining fluent api for CRUD operations.
Definition: crud.h:282
Template for defining fluent api for CRUD operations.
Definition: crud.h:166
Template for defining fluent api for CRUD operations.
Definition: crud.h:131
Template for defining fluent api for CRUD operations.
Definition: crud.h:242
Template for defining fluent api for CRUD operations.
Definition: crud.h:457
Template for defining fluent api for CRUD operations.
Definition: crud.h:201
LockContention
The LockContention enum defines constants for defining the row locking contention for Set_lock::lockE...
Definition: crud.h:117
Details for public API classes representing CRUD operations.
Type
Types that can be reported in result meta-data.
Definition: result.h:241
internal::Expression expr(std::string &&e)
Function which indicates that a given string should be treated as expression.
Definition: document.h:638