document.h 19 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  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. #ifndef MYSQLX_DOCUMENT_H
  31. #define MYSQLX_DOCUMENT_H
  32. /**
  33. @file
  34. Declaration of DbDoc and related classes.
  35. */
  36. #include "common.h"
  37. #include <memory>
  38. #include <stdint.h>
  39. #include <limits>
  40. #include <vector>
  41. #include <assert.h>
  42. #undef min
  43. #undef max
  44. namespace mysqlx {
  45. MYSQLX_ABI_BEGIN(2,0)
  46. class Value;
  47. class DbDoc;
  48. class DocResult;
  49. class SessionSettings;
  50. namespace internal{
  51. class Schema_detail;
  52. } //internal
  53. using Field = std::string;
  54. // Document class
  55. // ==============
  56. /**
  57. Represents a collection of key-value pairs where value can be a scalar
  58. or another document.
  59. @note Internal document implementation is shared among DbDoc instances
  60. and thus using DbDoc objects should be cheap.
  61. @ingroup devapi_res
  62. */
  63. class PUBLIC_API DbDoc
  64. : public common::Printable
  65. {
  66. // TODO: move PUBLIC_API stuff to a detail class
  67. class INTERNAL Impl;
  68. DLL_WARNINGS_PUSH
  69. std::shared_ptr<Impl> m_impl;
  70. DLL_WARNINGS_POP
  71. INTERNAL DbDoc(const std::shared_ptr<Impl>&);
  72. const char* get_json() const;
  73. public:
  74. /**
  75. Create null document instance.
  76. @note Null document is different from empty document that has
  77. no fields.
  78. */
  79. DbDoc() {}
  80. /**
  81. Creates DbDoc instance out of given JSON string description.
  82. */
  83. explicit DbDoc(const std::string&);
  84. explicit DbDoc(std::string&&);
  85. /**
  86. Check if document is null
  87. */
  88. bool isNull() const { return NULL == m_impl.get(); }
  89. operator bool() const { return !isNull(); }
  90. /**
  91. Check if named field is a top-level field in the document.
  92. */
  93. virtual bool hasField(const Field&) const;
  94. /**
  95. Return Value::XXX constant that identifies type of value
  96. stored at given field.
  97. */
  98. virtual int fieldType(const Field&) const;
  99. /**
  100. Return value of given field.
  101. */
  102. virtual const Value& operator[](const Field&) const;
  103. const Value& operator[](const char *name) const
  104. {
  105. return this->operator[](Field(name));
  106. }
  107. const Value& operator[](const mysqlx::string &name) const
  108. {
  109. return this->operator[](Field(name));
  110. }
  111. /**
  112. Print JSON description of the document.
  113. */
  114. virtual void print(std::ostream&) const;
  115. /**
  116. Iterator instance can iterate over (top-level) fields of a document.
  117. A new iterator is obtained from begin() method.
  118. @note Only one instance of an iterator can be used at a time (not
  119. thread safe!).
  120. */
  121. class Iterator;
  122. virtual Iterator begin();
  123. virtual Iterator end();
  124. friend Impl;
  125. friend DocResult;
  126. friend Value;
  127. /// \cond Note: Ignore by doxygen
  128. friend internal::Schema_detail;
  129. /// \endcond
  130. };
  131. class PUBLIC_API DbDoc::Iterator
  132. {
  133. DLL_WARNINGS_PUSH
  134. std::shared_ptr<DbDoc::Impl> m_impl;
  135. DLL_WARNINGS_POP
  136. bool m_end;
  137. public:
  138. Iterator& operator++();
  139. bool operator==(const Iterator&) const;
  140. bool operator!=(const Iterator &other) const { return !(*this == other); }
  141. const Field& operator*();
  142. friend DbDoc;
  143. };
  144. // Value class
  145. // ===========
  146. /**
  147. %Value object can store value of scalar type, string, array or document.
  148. Implicit conversions to and from corresponding C++ types are defined.
  149. If conversion to wrong type is attempted, an error is thrown. If Value
  150. object holds an array or document, then array elements or fields of
  151. the document can be accessed using operator[]. Array values can be used
  152. as STL containers.
  153. Only direct conversions of stored value to the corresponding C++ type
  154. are supported. There are no implicit number->string conversions etc.
  155. Values of type RAW can refer to a region of memory containing raw bytes.
  156. Such values are created from `bytes` and can by casted to `bytes` type.
  157. @note Value object copies the values it stores. Thus, after storing value
  158. in Value object, the original value can be destroyed without invalidating
  159. the copy. This includes RAW Values which hold a copy of bytes.
  160. @ingroup devapi_res
  161. */
  162. class Value
  163. : public virtual common::Printable
  164. , protected common::Value
  165. {
  166. public:
  167. using string = mysqlx::string;
  168. /**
  169. Possible types of values.
  170. @sa getType()
  171. */
  172. enum Type
  173. {
  174. VNULL, ///< Null value
  175. UINT64, ///< Unsigned integer
  176. INT64, ///< Signed integer
  177. FLOAT, ///< Float number
  178. DOUBLE, ///< Double number
  179. BOOL, ///< Boolean
  180. STRING, ///< String
  181. DOCUMENT, ///< Document
  182. RAW, ///< Raw bytes
  183. ARRAY, ///< Array of values
  184. };
  185. typedef std::vector<Value>::iterator iterator;
  186. typedef std::vector<Value>::const_iterator const_iterator;
  187. ///@name Value Constructors
  188. ///@{
  189. Value(); ///< Constructs Null value.
  190. Value(std::nullptr_t); ///< Constructs Null value.
  191. Value(const mysqlx::string &str);
  192. Value(mysqlx::string &&str);
  193. //Value(const char16_t *str) : Value(mysqlx::string(str)) {}
  194. Value(const std::string &str);
  195. Value(std::string &&str);
  196. Value(const char *str) : Value(std::string(str)) {}
  197. template <typename C>
  198. Value(const std::basic_string<C> &str)
  199. : Value(mysqlx::string(str))
  200. {}
  201. template <typename C>
  202. Value(const C *str)
  203. : Value(mysqlx::string(str))
  204. {}
  205. Value(const bytes&);
  206. Value(int64_t);
  207. Value(uint64_t);
  208. Value(float);
  209. Value(double);
  210. Value(bool);
  211. Value(const DbDoc& doc);
  212. Value(const std::initializer_list<Value> &list);
  213. template <typename Iterator>
  214. Value(Iterator begin_, Iterator end_);
  215. ///@}
  216. Value(common::Value &&other);
  217. Value(const common::Value &other);
  218. Value(const Value&) = default;
  219. #ifdef HAVE_MOVE_CTORS
  220. Value(Value&&) = default;
  221. #else
  222. // Note move ctor implemented using move assignment defined below.
  223. Value(Value &&other)
  224. {
  225. *this = std::move(other);
  226. }
  227. #endif
  228. /*
  229. Note: These templates are needed to disambiguate constructor resolution
  230. for integer types.
  231. */
  232. template <
  233. typename T,
  234. typename std::enable_if<std::is_signed<T>::value>::type* = nullptr
  235. >
  236. Value(T x)
  237. : Value(static_cast<int64_t>(x))
  238. {}
  239. template <
  240. typename T,
  241. typename std::enable_if<std::is_unsigned<T>::value>::type* = nullptr
  242. >
  243. Value(T x)
  244. : Value(static_cast<uint64_t>(x))
  245. {}
  246. Value& operator=(const Value&) = default;
  247. /*
  248. Note: Move assignment is defined explicitly to avoid problems with
  249. virtual Printable base.
  250. */
  251. Value& operator=(Value&&);
  252. /*
  253. Assignment is implemented in terms of constructors: first an instance
  254. is created from the input data and then move assignment is used to place
  255. the result into this instance.
  256. */
  257. template<typename T>
  258. Value& operator=(T&& x)
  259. {
  260. try {
  261. *this = Value(std::forward<T>(x));
  262. return *this;
  263. }
  264. CATCH_AND_WRAP
  265. }
  266. public:
  267. /**
  268. @name Conversion to C++ Types
  269. Attempt to convert value of non-compatible type throws an error.
  270. */
  271. //@{
  272. operator int() const;
  273. operator unsigned() const;
  274. operator int64_t() const;
  275. operator uint64_t() const;
  276. operator float() const;
  277. operator double() const;
  278. explicit operator bool() const;
  279. operator mysqlx::string() const;
  280. explicit operator std::string() const;
  281. template <typename C>
  282. explicit operator std::basic_string<C>() const
  283. {
  284. return this->operator mysqlx::string();
  285. }
  286. explicit operator bytes() const;
  287. operator DbDoc() const;
  288. template<typename T>
  289. T get() const;
  290. //@}
  291. bytes getRawBytes() const
  292. {
  293. try {
  294. size_t len;
  295. const byte *ptr = get_bytes(&len);
  296. return { ptr, len };
  297. }
  298. CATCH_AND_WRAP
  299. }
  300. /**
  301. Return type of the value stored in this instance (or VNULL if no
  302. value is stored).
  303. */
  304. Type getType() const;
  305. /// Convenience method for checking if value is null.
  306. bool isNull() const
  307. {
  308. return VNULL == getType();
  309. }
  310. /**
  311. Check if document value contains given (top-level) field.
  312. Throws error if this is not a document value.
  313. */
  314. bool hasField(const Field&) const;
  315. /**
  316. If this value is not a document, throws error. Otherwise
  317. returns value of given field of the document.
  318. */
  319. const Value& operator[](const Field&) const;
  320. const Value& operator[](const char *name) const
  321. { return (*this)[Field(name)]; }
  322. const Value& operator[](const mysqlx::string &name) const
  323. { return (*this)[Field(name)]; }
  324. /**
  325. Access to elements of an array value.
  326. If non-array value is accessed like an array, an error is thrown.
  327. */
  328. //@{
  329. iterator begin();
  330. const_iterator begin() const;
  331. iterator end();
  332. const_iterator end() const;
  333. size_t elementCount() const;
  334. const Value& operator[](unsigned) const;
  335. const Value& operator[](int pos) const
  336. {
  337. assert(pos >= 0);
  338. return operator[]((unsigned)pos);
  339. }
  340. //@}
  341. /// Print the value to a stream.
  342. void print(std::ostream &out) const
  343. {
  344. switch (m_type)
  345. {
  346. case DOC: out << m_doc; return;
  347. case ARR:
  348. {
  349. bool first = true;
  350. out << "[";
  351. for (auto it = m_arr->begin();it!=m_arr->end();++it)
  352. {
  353. if (!first)
  354. {
  355. out << ", ";
  356. }
  357. else
  358. {
  359. first = false;
  360. }
  361. switch (it->get_type())
  362. {
  363. case common::Value::STRING:
  364. case common::Value::USTRING:
  365. case common::Value::EXPR:
  366. out << R"(")" << *it << R"(")";
  367. break;
  368. default:
  369. out << *it;
  370. break;
  371. }
  372. }
  373. out << "]";
  374. return;
  375. }
  376. default: common::Value::print(out); return;
  377. }
  378. }
  379. protected:
  380. enum { VAL, ARR, DOC } m_type = VAL;
  381. void check_type(Type t) const
  382. {
  383. if (getType() != t)
  384. throw Error("Invalid value type");
  385. }
  386. bool is_expr() const
  387. {
  388. return VAL == m_type && common::Value::EXPR == common::Value::get_type();
  389. }
  390. void set_as_expr()
  391. {
  392. common::Value::m_type = common::Value::EXPR;
  393. }
  394. /*
  395. TODO: Instead extend common::Value with array and document types. Requires
  396. moving DbDoc code to the common layer.
  397. */
  398. typedef std::vector<Value> Array;
  399. DLL_WARNINGS_PUSH
  400. DbDoc m_doc;
  401. // Note: shared with other Value instances for the same array.
  402. std::shared_ptr<Array> m_arr;
  403. DLL_WARNINGS_POP
  404. public:
  405. friend SessionSettings;
  406. friend DbDoc;
  407. ///@cond IGNORE
  408. friend mysqlx::string;
  409. ///@endcond IGNORE
  410. struct INTERNAL Access;
  411. friend Access;
  412. };
  413. static const Value nullvalue;
  414. inline
  415. Value& Value::operator=(Value &&other)
  416. {
  417. m_type = other.m_type;
  418. switch (m_type)
  419. {
  420. case VAL:
  421. common::Value::operator=(std::move(other));
  422. break;
  423. case DOC: m_doc = std::move(other.m_doc); break;
  424. case ARR: m_arr = std::move(other.m_arr); break;
  425. default: break;
  426. }
  427. return *this;
  428. }
  429. namespace internal {
  430. /*
  431. Helper class to identify usage of expressions
  432. */
  433. class Expression
  434. : public mysqlx::Value
  435. {
  436. Expression()
  437. {}
  438. template <typename V>
  439. Expression(V&& val)
  440. : Value(std::forward<V>(val))
  441. {
  442. set_as_expr();
  443. }
  444. template <typename V>
  445. Expression(const V& val)
  446. : Value(val)
  447. {
  448. set_as_expr();
  449. }
  450. friend Expression expr(std::string&& s);
  451. friend Expression expr(const std::string& s);
  452. };
  453. /**
  454. Function which indicates that a given string should be treated
  455. as expression.
  456. If `s` is a string value, then in contexts where values are
  457. expected, `expr(s)` treats `s` as a DevAPI expression. For
  458. example statement
  459. table.select("foo > 1").execute();
  460. returns the string `"foo 1"` for each row in the table while
  461. table.select(expr("foo > 1")).execute();
  462. returns true/false, depending on the value of the expression.
  463. @ingroup devapi
  464. */
  465. inline
  466. internal::Expression expr(std::string&& e)
  467. {
  468. return std::forward<std::string>(e);
  469. }
  470. inline
  471. internal::Expression expr(const std::string& e)
  472. {
  473. return e;
  474. }
  475. } // internal
  476. using internal::expr;
  477. inline
  478. Value::Type Value::getType() const
  479. {
  480. switch (m_type)
  481. {
  482. case ARR: return ARRAY;
  483. case DOC: return DOCUMENT;
  484. case VAL:
  485. switch (common::Value::get_type())
  486. {
  487. case common::Value::VNULL: return VNULL;
  488. case common::Value::UINT64: return UINT64;
  489. case common::Value::INT64: return INT64;
  490. case common::Value::FLOAT: return FLOAT;
  491. case common::Value::DOUBLE: return DOUBLE;
  492. case common::Value::BOOL: return BOOL;
  493. case common::Value::STRING: return STRING;
  494. case common::Value::USTRING: return STRING;
  495. case common::Value::RAW: return RAW;
  496. case common::Value::EXPR: return STRING;
  497. case common::Value::JSON: return DOCUMENT;
  498. }
  499. }
  500. return VNULL; // quiet compiler warning
  501. }
  502. /*
  503. Value type conversions
  504. ----------------------
  505. TODO: more informative errors
  506. */
  507. inline
  508. Value::Value(const std::initializer_list<Value> &list)
  509. : m_type(ARR)
  510. {
  511. try {
  512. m_arr = std::make_shared<Array>(list);
  513. }
  514. CATCH_AND_WRAP
  515. }
  516. template <typename Iterator>
  517. inline
  518. Value::Value(Iterator begin_, Iterator end_)
  519. : m_type(ARR)
  520. {
  521. try {
  522. m_arr = std::make_shared<Array>(begin_, end_);
  523. }
  524. CATCH_AND_WRAP
  525. }
  526. inline
  527. Value::Value(common::Value &&other)
  528. try
  529. : common::Value(std::move(other))
  530. {}
  531. CATCH_AND_WRAP
  532. inline
  533. Value::Value(const common::Value &other)
  534. try
  535. : common::Value(other)
  536. {}
  537. CATCH_AND_WRAP
  538. inline Value::Value()
  539. {}
  540. inline Value::Value(std::nullptr_t)
  541. {}
  542. inline Value::Value(int64_t val)
  543. try
  544. : common::Value(val)
  545. {}
  546. CATCH_AND_WRAP
  547. inline Value::Value(uint64_t val)
  548. try
  549. : common::Value(val)
  550. {}
  551. CATCH_AND_WRAP
  552. template <>
  553. PUBLIC_API common::Value Value::get<common::Value>() const;
  554. template<>
  555. inline
  556. int Value::get<int>() const
  557. {
  558. try {
  559. int64_t val = get_sint();
  560. if (val > std::numeric_limits<int>::max())
  561. throw Error("Numeric conversion overflow");
  562. if (val < std::numeric_limits<int>::min())
  563. throw Error("Numeric conversion overflow");
  564. return (int)val;
  565. }
  566. CATCH_AND_WRAP
  567. }
  568. inline
  569. Value::operator int() const
  570. {
  571. return get<int>();
  572. }
  573. template<>
  574. inline unsigned Value::get<unsigned>() const
  575. {
  576. try {
  577. uint64_t val = get_uint();
  578. if (val > std::numeric_limits<unsigned>::max())
  579. throw Error("Numeric conversion overflow");
  580. return (unsigned)val;
  581. }
  582. CATCH_AND_WRAP
  583. }
  584. inline
  585. Value::operator unsigned() const
  586. {
  587. return get<unsigned>();
  588. }
  589. template<>
  590. inline int64_t Value::get<int64_t>() const
  591. {
  592. try {
  593. return get_sint();
  594. }
  595. CATCH_AND_WRAP
  596. }
  597. inline
  598. Value::operator int64_t() const
  599. {
  600. return get<int64_t>();
  601. }
  602. template<>
  603. inline uint64_t Value::get<uint64_t>() const
  604. {
  605. try {
  606. return get_uint();
  607. }
  608. CATCH_AND_WRAP
  609. }
  610. inline
  611. Value::operator uint64_t() const
  612. {
  613. return get<uint64_t>();
  614. }
  615. inline Value::Value(float val)
  616. try
  617. : common::Value(val)
  618. {}
  619. CATCH_AND_WRAP
  620. template<>
  621. inline
  622. float Value::get<float>() const
  623. {
  624. try {
  625. return get_float();
  626. }
  627. CATCH_AND_WRAP
  628. }
  629. inline
  630. Value::operator float() const
  631. {
  632. return get<float>();
  633. }
  634. inline Value::Value(double val)
  635. try
  636. : common::Value(val)
  637. {}
  638. CATCH_AND_WRAP
  639. template<>
  640. inline
  641. double Value::get<double>() const
  642. {
  643. try {
  644. return get_double();
  645. }
  646. CATCH_AND_WRAP
  647. }
  648. inline
  649. Value::operator double() const
  650. {
  651. return get<double>();
  652. }
  653. inline Value::Value(bool val)
  654. try
  655. : common::Value(val)
  656. {}
  657. CATCH_AND_WRAP
  658. template<>
  659. inline
  660. bool Value::get<bool>() const
  661. {
  662. try {
  663. return get_bool();
  664. }
  665. CATCH_AND_WRAP
  666. }
  667. inline
  668. Value::operator bool() const
  669. {
  670. return get<bool>();
  671. }
  672. inline Value::Value(const DbDoc &doc)
  673. try
  674. : m_type(DOC)
  675. , m_doc(doc)
  676. {}
  677. CATCH_AND_WRAP
  678. inline Value::Value(const mysqlx::string &val)
  679. try
  680. : common::Value(val)
  681. {}
  682. CATCH_AND_WRAP
  683. inline Value::Value(mysqlx::string &&val)
  684. try
  685. : common::Value(std::move(val))
  686. {}
  687. CATCH_AND_WRAP
  688. inline Value::Value(const std::string &val)
  689. try
  690. : common::Value(val)
  691. {}
  692. CATCH_AND_WRAP
  693. inline Value::Value(std::string &&val)
  694. try
  695. : common::Value(std::move(val))
  696. {}
  697. CATCH_AND_WRAP
  698. template<>
  699. inline
  700. std::wstring Value::get<std::wstring>() const
  701. {
  702. try {
  703. return mysqlx::string(this->get_ustring());
  704. }
  705. CATCH_AND_WRAP
  706. }
  707. template<>
  708. inline
  709. std::string Value::get<std::string>() const
  710. {
  711. try {
  712. return get_string();
  713. }
  714. CATCH_AND_WRAP
  715. }
  716. inline
  717. Value::operator std::string() const
  718. {
  719. return get<std::string>();
  720. }
  721. template<>
  722. inline
  723. mysqlx::string Value::get<mysqlx::string>() const
  724. {
  725. try {
  726. return this->get_ustring();
  727. }
  728. CATCH_AND_WRAP
  729. }
  730. inline
  731. Value::operator mysqlx::string() const
  732. {
  733. return get<mysqlx::string>();
  734. }
  735. inline Value::Value(const bytes &data)
  736. try
  737. : common::Value(data.begin(), data.length())
  738. {}
  739. CATCH_AND_WRAP
  740. template<>
  741. inline
  742. bytes Value::get<bytes>() const
  743. {
  744. return getRawBytes();
  745. }
  746. inline
  747. Value::operator bytes() const
  748. {
  749. return get<bytes>();
  750. }
  751. template<>
  752. inline
  753. DbDoc Value::get<DbDoc>() const
  754. {
  755. check_type(DOCUMENT);
  756. return m_doc;
  757. }
  758. inline
  759. Value::operator DbDoc() const
  760. {
  761. return get<DbDoc>();
  762. }
  763. inline
  764. bool Value::hasField(const Field &fld) const
  765. {
  766. check_type(DOCUMENT);
  767. return m_doc.hasField(fld);
  768. }
  769. inline
  770. const Value& Value::operator[](const Field &fld) const
  771. {
  772. check_type(DOCUMENT);
  773. return m_doc[fld];
  774. }
  775. inline
  776. int DbDoc::fieldType(const Field &fld) const
  777. {
  778. return (*this)[fld].getType();
  779. }
  780. // Array access
  781. inline
  782. Value::iterator Value::begin()
  783. {
  784. if (ARR != m_type)
  785. throw Error("Attempt to iterate over non-array value");
  786. return m_arr->begin();
  787. }
  788. inline
  789. Value::const_iterator Value::begin() const
  790. {
  791. if (ARR != m_type)
  792. throw Error("Attempt to iterate over non-array value");
  793. return m_arr->begin();
  794. }
  795. inline
  796. Value::iterator Value::end()
  797. {
  798. if (ARR != m_type)
  799. throw Error("Attempt to iterate over non-array value");
  800. return m_arr->end();
  801. }
  802. inline
  803. Value::const_iterator Value::end() const
  804. {
  805. if (ARR != m_type)
  806. throw Error("Attempt to iterate over non-array value");
  807. return m_arr->end();
  808. }
  809. inline
  810. const Value& Value::operator[](unsigned pos) const
  811. {
  812. check_type(ARRAY);
  813. return m_arr->at(pos);
  814. }
  815. inline
  816. size_t Value::elementCount() const
  817. {
  818. check_type(ARRAY);
  819. return m_arr->size();
  820. }
  821. MYSQLX_ABI_END(2,0)
  822. } // mysqlx
  823. #endif