document.h 20 KB

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