1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef ZORBA_STORE_ITEM_H 17 #define ZORBA_STORE_ITEM_H 18 19 #include <iostream> 20 #include <vector> 21 22 #include <zorba/config.h> 23 #include <zorba/store_consts.h> 24 #include <zorba/streams.h> 25 26 #include "zorbatypes/rclock.h" 27 #include "zorbatypes/schema_types.h" 28 29 #include <zorba/store_consts.h> 30 #include "store/api/shared_types.h" 31 32 #ifndef ZORBA_NO_FULL_TEXT 33 #include <zorba/locale.h> 34 #include <zorba/tokenizer.h> 35 #include "store/api/ft_token_iterator.h" 36 #endif /* ZORBA_NO_FULL_TEXT */ 37 38 namespace zorba 39 { 40 41 class ZorbaException; 42 43 namespace store 44 { 45 46 typedef StoreConsts::NodeKind NodeKind; 47 48 /** 49 * Class Item represents an "item" as defined by the XQuery Data Model (XDM) 50 * [http://www.w3.org/TR/xquery-semantics/doc-fs-Item] 51 */ 52 class ZORBA_DLL_PUBLIC Item 53 { 54 public: 55 enum ItemKind 56 { 57 NODE = 0x10, 58 ATOMIC = 0x21, 59 PUL = 0x41, 60 FUNCTION = 0x81, 61 LIST = 0x101, 62 #ifdef ZORBA_WITH_JSON 63 JSONIQ = 0x201, 64 #endif 65 ERROR_ = 0x401 66 }; 67 68 protected: 69 typedef union 70 { 71 long * treeRCPtr; 72 long itemKind; 73 } 74 ItemUnion; 75 76 77 protected: 78 mutable long theRefCount; 79 mutable ItemUnion theUnion; 80 81 protected: 82 Item()83 Item() : theRefCount(0) 84 { 85 theUnion.treeRCPtr = 0; 86 } 87 Item(ItemKind k)88 Item(ItemKind k) : theRefCount(0) 89 { 90 theUnion.itemKind = k; 91 } 92 93 public: 94 ~Item()95 virtual ~Item() {} 96 free()97 virtual void free() { delete this; } 98 getRefCount()99 long getRefCount() const { return theRefCount; } 100 getSharedRefCounter()101 long* getSharedRefCounter() const { return theUnion.treeRCPtr; } 102 103 void addReference() const; 104 105 void removeReference(); 106 107 108 /* ------------------- General Methods for Items ------------------------- */ 109 110 /** 111 * @return the kind of the item 112 */ 113 ItemKind getKind() const; 114 115 /** 116 * @return "true" if the item is a node 117 */ 118 bool 119 isNode() const; 120 121 #ifdef ZORBA_WITH_JSON 122 /** 123 * @return "true" if the item is a JSON item 124 */ 125 bool 126 isJSONItem() const; 127 #endif 128 129 /** 130 * @return "true" if the item is an atomic value 131 */ 132 bool 133 isAtomic() const; 134 135 /** 136 * @return "true" if the item is an list of atomic values 137 */ 138 bool 139 isList() const; 140 141 /** 142 * @return "true" if the item is a pending update list 143 */ 144 bool 145 isPul() const; 146 147 /** 148 * @return "true" if the item is an error. 149 */ 150 bool 151 isError() const; 152 153 /** 154 * @return "true" if the item is a function. 155 */ 156 bool 157 isFunction() const; 158 159 /** 160 * @return a string representation of the item's kind 161 */ 162 zstring printKind() const; 163 164 #ifdef ZORBA_WITH_JSON 165 /** 166 * @return "true" if the item is a JSON object item 167 */ 168 virtual bool 169 isJSONObject() const; 170 171 /** 172 * @return "true" if the item is a JSON array item 173 */ 174 virtual bool 175 isJSONArray() const; 176 #endif 177 178 /** 179 * @return (dynamic) XQuery type of the item 180 */ 181 virtual Item* 182 getType() const; 183 184 /** 185 * Get a hash value computed from the value of this item. 186 * 187 * @param RuntimeCB the runtime control block that contains the 188 * dynamic and static context 189 * 190 * @param An optional XQPCollator that is used for hasing string 191 * items 192 * 193 * @return The hash value 194 */ 195 virtual uint32_t 196 hash(long timezone = 0, const XQPCollator* aCollation = 0) const; 197 198 /** 199 * Compares (by value) two items for equality. 200 * 201 * @param An optional XQPCollator that is used for comparing string items 202 * @return true, if the two items are the "same" 203 * @throws ZSTR0040_TYPE_ERROR if the items are not equality-comparable. For two 204 * items to be equality-comparable, one has to be a subtype of the other 205 * and they must also be comparable by the eq operator as specified in 206 * the table of http://www.w3.org/TR/xquery/#mapping. 207 */ 208 virtual bool 209 equals(const Item*, long timezone = 0, const XQPCollator* aCollation = 0) const; 210 211 /** 212 * Compares (by value) two items, returning < 0 if "this" is less than "other", 213 * 0 if "this" and "other" are equal, and > 0 if "this" is greater than "other". 214 * 215 * @param aCollation An optional XQPCollator that is used for comparing string items 216 * @return < 0 if "this" is less than "other", 0 if "this" and "other" are 217 * equal, and > 0 if "this" is greater than "other". 218 * @throws ZSTR0040_TYPE_ERROR if the items are not order-comparable. For two 219 * items to be order-comparable, one has to be a subtype of the other 220 * and they must also be comparable by the gt operator as specified in 221 * the table of http://www.w3.org/TR/xquery/#mapping. 222 * @throws ZSTR0041_NAN_COMPARISON if both "this" and "other" are xs:double 223 * or xs:float and at leat one of the items is NaN. 224 */ 225 virtual long 226 compare(const Item* other, long timezone = 0, const XQPCollator* aCollation = 0) const; 227 228 /** 229 * Computes the Effective Boolean Value for that item as specified in the 230 * XQuery Functions & Operators specification (Section 15.1.1). 231 * 232 * @return result of Effective Boolean Value 233 */ 234 virtual bool 235 getEBV() const; 236 237 /** 238 * @return string value of the item as defined in XQuery data model 239 * specification (Section 2.6.5). 240 */ 241 virtual zstring 242 getStringValue() const; 243 244 virtual void 245 getStringValue2(zstring& result) const; 246 247 /** 248 * Append the string value of this item to the given string. 249 * 250 * @param buf The string at the end of which the string value of this item 251 * will be appended. 252 */ 253 virtual void 254 appendStringValue(zstring& buf) const; 255 256 257 /** 258 * Get the typed value of an item. If the item is an atomic item, its typed 259 * value is the item itself. If it is a node, its typed value is defined 260 * according to the XDM. 261 * 262 * @param val If the typed value consists of a single atomic value, it is 263 * returned in val. Otherwise, val is set to NULL. 264 * @param iter If the typed value is a sequence of atomic values, an iterator 265 * is created to iterate over the values of the sequence. Otherwise, 266 * iter is set to NULL. 267 */ 268 virtual void 269 getTypedValue(Item_t& val, Iterator_t& iter) const; 270 271 /** Method to print to content of the Item 272 */ 273 virtual zstring 274 show() const; 275 276 /* ------------------- Methods for AtomicValues ------------------------------ */ 277 278 /** 279 * @return The numeric code coresponding to the data type of this item. 280 */ 281 virtual SchemaTypeCode getTypeCode() const; 282 283 /** 284 * @return If this is an atomic item with a user-defined data type UT, return 285 * the underlying atomic item that stores the actual value and whose 286 * data type is a builtin atomic supertype of UT. Otherwise, return NULL. 287 */ 288 virtual store::Item* getBaseItem() const; 289 290 /** 291 * getXValue functions: 292 * @return value of type X 293 * 294 * Assuming that the item is an AtomicValue of a particular kind X, return the 295 * value of the item. Implementations of X, e.g., a specific DoubleValue 296 * implementation, will override its specific getXValue method (i.e., 297 * getDoubleValue) and not change any of the other methods. Implementations of 298 * the seven kinds of nodes should not override the definition of these methods. 299 */ 300 301 /** Accessor for xs:string and its subtypes 302 */ 303 virtual const zstring& getString() const; 304 305 /** Accessor for xs:base64Binary 306 */ 307 virtual const char* getBase64BinaryValue(size_t& size) const; 308 309 /** 310 * Checks whether a base64 item's content is already encoded 311 * 312 * @return true only if it is. 313 */ 314 virtual bool isEncoded() const; 315 316 /** Accessor for xs:boolean 317 */ 318 virtual bool getBooleanValue() const; 319 320 /** Accessor for xs:double 321 */ 322 virtual xs_double getDoubleValue() const; 323 324 /** 325 * Accessor for xs:float 326 */ 327 virtual xs_float getFloatValue() const; 328 329 /** 330 * Accessor for xs:decimal, xs:nonPositiveInteger, negativeInteger, 331 * nonNegativeInteger, positive)integer, xs:long, xs:unsignedLong, 332 * xs:(unsigned)int, xs:(unsigned)short, xs:(unsigned)byte 333 */ 334 virtual xs_decimal getDecimalValue() const; 335 336 /** Accessor for xs:(nonPositive | negative | nonNegativeInteger | positive)integer, 337 * xs:(unsigned)long, xs:(unsigned)int, xs:(unsigned)short, xs:(unsigned)byte 338 */ 339 virtual xs_integer 340 getIntegerValue() const; 341 342 /** Accessor for xs:nonNegativeInteager, xs:positiveInteger 343 */ 344 virtual xs_nonNegativeInteger 345 getUnsignedIntegerValue() const; 346 347 /** Accessor for xs:long 348 */ 349 virtual xs_long 350 getLongValue() const; 351 352 /** Accessor for xs:int 353 */ 354 virtual xs_int 355 getIntValue() const; 356 357 /** Accessor for xs:short 358 */ 359 virtual xs_short 360 getShortValue() const; 361 362 /** Accessor for xs:byte 363 */ 364 virtual xs_byte 365 getByteValue() const; 366 367 /** Accessor for xs:unsignedLong 368 */ 369 virtual xs_unsignedLong 370 getUnsignedLongValue() const; 371 372 /** Accessor for xs:nonNegativeIntegerValue, xs:positiveInteger, xs:unsignedInt 373 */ 374 virtual xs_unsignedInt 375 getUnsignedIntValue() const; 376 377 /** Accessor for xs:unsignedShort 378 */ 379 virtual xs_unsignedShort 380 getUnsignedShortValue() const; 381 382 /** Accessor for xs:unsignedChar, xs:unsignedByte 383 */ 384 virtual xs_unsignedByte 385 getUnsignedByteValue() const; 386 387 388 /** Accessor for xs:dateTime 389 */ 390 virtual const xs_dateTime& 391 getDateTimeValue() const; 392 393 /** Accessor for xs:date 394 */ 395 virtual const xs_date& 396 getDateValue() const; 397 398 /** Accessor for xs:time 399 */ 400 virtual const xs_time& 401 getTimeValue() const; 402 403 /** Accessor for xs:gYearMonth 404 */ 405 virtual const xs_gYearMonth& 406 getGYearMonthValue() const; 407 408 /** Accessor for xs:gYear 409 */ 410 virtual const xs_gYear& 411 getGYearValue() const; 412 413 /** Accessor for xs:gMonth 414 */ 415 virtual const xs_gMonth& 416 getGMonthValue() const; 417 418 /** Accessor for xs:gMonthDay 419 */ 420 virtual const xs_gMonthDay& 421 getGMonthDayValue() const; 422 423 /** Accessor for xs:gDay 424 */ 425 virtual const xs_gDay& 426 getGDayValue() const; 427 428 /** Accessor for xs:duration 429 */ 430 virtual const xs_duration& 431 getDurationValue() const; 432 433 434 /** Accessor for xs:dayTimeDuration 435 */ 436 virtual const xs_dayTimeDuration& 437 getDayTimeDurationValue() const; 438 439 440 /** Accessor for xs:yearMonthDuration 441 */ 442 virtual const xs_yearMonthDuration& 443 getYearMonthDurationValue() const; 444 445 446 /** Accessor for xs:hexBinary 447 */ 448 virtual xs_hexBinary 449 getHexBinaryValue() const; 450 451 452 /** 453 * Helper method for numeric atomic items 454 * @return true, if containing number is not-a-number (possible for 455 * floating-point numbers) 456 */ 457 virtual bool 458 isNaN() const; 459 460 461 /** 462 * Helper method for numeric atomic items 463 * @return true, if containing numbers represents -INF or +INF 464 */ 465 virtual bool 466 isPosOrNegInf() const; 467 468 /** 469 * 470 */ 471 virtual bool 472 isAttributeRef() const; 473 474 /** 475 * 476 */ 477 virtual bool 478 isCommentRef() const; 479 480 /** 481 * 482 */ 483 virtual bool 484 isDocumentRef() const; 485 486 /** 487 * 488 */ 489 virtual bool 490 isElementRef() const; 491 492 /** 493 * 494 */ 495 virtual bool 496 isProcessingInstructionRef() const; 497 498 /** 499 * 500 */ 501 virtual bool 502 isTextRef() const; 503 504 505 /* ------------------- Methods for Nodes ------------------------------------- */ 506 507 /** 508 * getNodeProperty functions - Accessor of XDM (see XDM specification, Section 5) 509 * 510 * Assuming that the item is a node, return the properties of that particular 511 * node. Since all these properties are defined on all seven kinds of nodes 512 * (documents, elements, attributes, etc.), the implementations of all seven 513 * kinds of nodes must override these methods. Implementations of atomic values 514 * should keep the default (error) implementation of these methods. 515 */ 516 517 /** 518 * If isValidated() is invoked on some item, it returns true if markValidated() 519 * has been called before on the root of the tree where the item belongs to, 520 * otherwise it returns false. Notice that validation is not done by the store, 521 * so the store itself cannot invoke the markValidated() method; it has to be 522 * invoked by the "user" of the store. 523 */ 524 virtual bool 525 isValidated() const; 526 527 /** 528 * Mark the item as validated. 529 */ 530 virtual void 531 markValidated(); 532 533 /** 534 * @return True if this is an element node with name N and it has at least one 535 * descendant whose name is also N. 536 * 537 * Note: This function is used purely for enabling certain optimizations in the 538 * query processor. As a result, it is not necessary that a store actually 539 * provides info about the recursivity of a node; such a store should 540 * provide a dummy implementation of this method that simply returns true. 541 */ 542 virtual bool 543 isRecursive() const; 544 545 /** Accessor for document node 546 * @return uri? 547 */ 548 virtual void 549 getDocumentURI(zstring& uri) const; 550 551 /** Accessor for document node, element node, attribute node, 552 * processing instruction node, comment node, text node 553 * @return uri? 554 */ 555 virtual void 556 getBaseURI(zstring& uri) const; 557 558 /** Accessor for element node 559 * @return attribute* 560 */ 561 virtual Iterator_t 562 getAttributes() const; 563 564 /** Accessor for document node, element node 565 * @return node* 566 */ 567 virtual Iterator_t 568 getChildren() const; 569 570 /** Accessor for attribute node 571 * @return isId: Used for attribute items (defines the attribute an id?) 572 */ 573 virtual bool 574 isId() const; 575 576 /** Accessor for attribute node 577 * @return isIdRefs Used for attribute (defines the attribute an idref?)) 578 */ 579 virtual bool 580 isIdRefs() const; 581 582 /** Accessor for element node 583 * @return true if this element node belongs to a substition group 584 */ 585 virtual bool 586 isInSubstitutionGroup() const; 587 588 /** Accessor for element node 589 * @return returns prefix namespace pairs 590 */ 591 virtual void 592 getNamespaceBindings( 593 NsBindings& bindings, 594 StoreConsts::NsScoping ns_scoping = StoreConsts::ALL_NAMESPACES) const; 595 596 /** Accessor for element node 597 * @return boolean? 598 */ 599 virtual Item_t 600 getNilled() const; 601 602 /** Accessor for document node, element node, attribute node, namespace node, 603 * processing instruction node, comment node, text node 604 * @return TypeCode of the current node 605 */ 606 virtual NodeKind 607 getNodeKind() const; 608 609 /** Accessor for element node, attribute node 610 * @return qname? 611 */ 612 virtual Item* 613 getNodeName() const; 614 615 /** 616 * If this item is a node and it belongs to a collection, return that 617 * collection. Otherwise, return 0. 618 * 619 * @return The collection this item belongs to, or NULL if item does not 620 * belong to any collection. 621 */ 622 virtual const Collection* 623 getCollection() const; 624 625 /** 626 * Accessor for element, attribute, processing instruction, comment, text nodes 627 * @return node? 628 */ 629 virtual Item* 630 getParent() const; 631 632 /** Accessor for xs:qname, namespace node 633 * @return namespace uri 634 */ 635 virtual const zstring& 636 getNamespace() const; 637 638 /** Accessor for xs:qname, namespace node 639 * @return namespace prefix 640 */ 641 virtual const zstring& 642 getPrefix() const; 643 644 /** Accessor for xs:qname 645 * @return namespace local name 646 */ 647 virtual const zstring& 648 getLocalName() const; 649 650 /** Accessor for document node 651 * @return unparsed entity public id 652 */ 653 virtual void 654 getUnparsedEntityPublicId(zstring& val) const; 655 656 /** Accessor for document node 657 * @return unparsed entity system id 658 */ 659 virtual void 660 getUnparsedEntitySystemId(zstring& val) const; 661 662 /** 663 * Accessor for processing instruction node 664 * @return target of the PI 665 */ 666 virtual const zstring& 667 getTarget() const; 668 669 /** 670 * Accessor for the name of the function item. 671 * Returns null for anonymous functions. 672 */ 673 virtual const Item_t 674 getFunctionName() const; 675 676 /** 677 * Make a copy of the xml tree rooted at this node and place the copied 678 * tree as the last child of a given node. 679 * 680 * @param parent The node P under which the copied tree is to be placed. 681 * P may be NULL, in which case the copied tree becomes a 682 * new standalone xml tree. 683 * @param copymode Encapsulates the construction-mode and copy-namespace-mode 684 * components of the query's static context. 685 * @return A pointer to the root node of the copied tree, or to this 686 * node if no copy was actually done. 687 */ 688 virtual Item* 689 copy(Item* parent, const CopyMode& copymode) const; 690 691 /** 692 * An optimization method used to indicate to the store that the construction 693 * of this node (including its children and attributes) is complete. Some 694 * stores may benefit from this information to do internal cleanup, memory 695 * management, or other optimizations when they know that a node has reached a 696 * "stable" state (e.g. after the initial creation of this node or after a 697 * set of updates). Other stores may just provide an empty implementation of 698 * this method. 699 */ 700 virtual void finalizeNode(); 701 702 /* - Methods for computing relationship and properties of a node - */ 703 704 /** 705 * 706 */ 707 virtual bool 708 isAncestor(const store::Item_t&) const; 709 710 /** 711 * 712 */ 713 virtual bool 714 isFollowingSibling(const store::Item_t&) const; 715 716 /** 717 * 718 */ 719 virtual bool 720 isFollowing(const store::Item_t&) const; 721 722 /** 723 * 724 */ 725 virtual bool 726 isInSubtreeOf(const store::Item_t&) const; 727 728 /** 729 * 730 */ 731 virtual bool 732 isDescendant(const store::Item_t&) const; 733 734 /** 735 * 736 */ 737 virtual bool 738 isPrecedingSibling(const store::Item_t&) const; 739 740 /** 741 * 742 */ 743 virtual bool 744 isPreceding(const store::Item_t&) const; 745 746 /** 747 * 748 */ 749 virtual bool 750 isChild(const store::Item_t&) const; 751 752 /** 753 * 754 */ 755 virtual bool 756 isAttribute(const store::Item_t&) const; 757 758 /** 759 * 760 */ 761 virtual bool 762 isParent(const store::Item_t&) const; 763 764 /** 765 * 766 */ 767 virtual bool 768 isPrecedingInDocumentOrder(const store::Item_t&) const; 769 770 /** 771 * 772 */ 773 virtual bool 774 isFollowingInDocumentOrder(const store::Item_t&) const; 775 776 /** 777 * 778 */ 779 virtual store::Item_t 780 getLevel() const; 781 782 /** 783 * 784 */ 785 virtual bool 786 isSibling(const store::Item_t&) const; 787 788 /** 789 * 790 */ 791 virtual bool 792 inSameTree(const store::Item_t&) const; 793 794 /** 795 * 796 */ 797 virtual bool 798 inCollection() const; 799 800 /** 801 * 802 */ 803 virtual bool 804 inSameCollection(const store::Item_t&) const; 805 806 /** 807 * 808 */ 809 virtual store::Item_t 810 leastCommonAncestor(const store::Item_t&) const; 811 812 813 #ifdef ZORBA_WITH_JSON 814 /* -------------------- Methods for JSON items --------------------- */ 815 816 /** 817 * @return the kind of the json item 818 */ 819 virtual store::StoreConsts::JSONItemKind 820 getJSONItemKind() const; 821 822 /** 823 * defined on JSONArray 824 * (jdm:size accessor on an array) 825 * @return the number of values in the array. 826 */ 827 virtual xs_integer 828 getArraySize() const; 829 830 /** 831 * defined on JSONArray 832 * (jdm:value accessor on an array) 833 * @return the value of the json array at a given position 834 */ 835 virtual store::Item_t 836 getArrayValue(const xs_integer& position) const; 837 838 /** 839 * defined on JSONArray 840 * (not an accessor) 841 * @return the values of a given array 842 */ 843 virtual store::Iterator_t 844 getArrayValues() const; 845 846 /** 847 * defined on JSONObject 848 * (jdm:keys accessor on an object) 849 * @return the keys of an object. 850 */ 851 virtual store::Iterator_t 852 getObjectKeys() const; 853 854 /** 855 * defined on JSONObject 856 * (jdm:value accessor on an object) 857 * @return the value associated with a given key 858 */ 859 virtual store::Item_t 860 getObjectValue(const store::Item_t& key) const; 861 862 #endif // ZORBA_WITH_JSON 863 864 865 /* -------------------- Methods for ErrorItem --------------------- */ 866 867 virtual ZorbaException* getError() const; 868 869 /* -------------------- Methods for streamability ----------------- */ 870 871 /** 872 * Checks whether the item's content is streamable. 873 * 874 * @return true only if it is. 875 */ 876 virtual bool isStreamable() const; 877 878 /** 879 * Checks whether the item's content is streamable 880 * and the underlying stream is seekable 881 * 882 * @return true only if it is. 883 */ 884 virtual bool isSeekable() const; 885 886 /** 887 * Gets an istream for the item's content. 888 * 889 * @return the stream. 890 * @throw ZorbaException if the item is not streamable. 891 */ 892 virtual std::istream& getStream(); 893 894 /** 895 * Gets the StreamReleaser associated with this item. 896 * 897 * @return the StreamReleaser. 898 * @throw ZorbaException if the item is not streamable. 899 */ 900 virtual StreamReleaser getStreamReleaser(); 901 902 /** 903 * Sets the StreamReleaser associated with this item. 904 * 905 * @throw ZorbaException if the item is not streamable. 906 */ 907 virtual void setStreamReleaser(StreamReleaser aReleaser); 908 909 /* -------------------- Methods for Full-Text --------------------- */ 910 911 #ifndef ZORBA_NO_FULL_TEXT 912 /** 913 * Gets the tokens for this item. 914 * 915 * @param provider The TokenizerProvider to use. 916 * @param state The Tokenizer::State to use. 917 * @param lang The language to use for tokenization. 918 * @param wildcards If \c true, allow XQuery wildcard syntax. 919 * @return Returns an iterator over the tokens. 920 */ 921 virtual FTTokenIterator_t 922 getTokens(TokenizerProvider const &provider, Tokenizer::State &state, 923 locale::iso639_1::type lang, bool wildcards = false) const; 924 #endif /* ZORBA_NO_FULL_TEXT */ 925 926 927 private: 928 Item(const Item& other); 929 Item& operator=(const Item&); 930 }; 931 932 } // namespace store 933 } // namespace zorba 934 935 #endif /* ZORBA_STORE_ITEM_H */ 936 /* 937 * Local variables: 938 * mode: c++ 939 * End: 940 */ 941 /* vim:set et sw=2 ts=2: */ 942