16
16
#include "stdafx.h"
22
#include <libxml/parser.h>
24
#include "zorbautils/hashfun.h"
25
#include "zorbautils/fatal.h"
26
#include "zorbatypes/rchandle.h"
27
#include "diagnostics/xquery_diagnostics.h"
28
#include "diagnostics/assert.h"
29
#include "diagnostics/util_macros.h"
31
#include "store/api/pul.h"
33
#include "store/naive/properties.h"
34
#include "store/naive/string_pool.h"
35
#include "store/naive/simple_store.h"
36
#include "store/naive/simple_temp_seq.h"
37
#include "store/naive/simple_lazy_temp_seq.h"
38
#include "store/naive/simple_collection.h"
39
#include "store/naive/collection_set.h"
40
#include "store/naive/simple_index.h"
41
#include "store/naive/simple_index_value.h"
42
#include "store/naive/simple_index_general.h"
43
#include "store/naive/simple_ic.h"
44
#include "store/naive/qname_pool.h"
45
#include "store/naive/loader.h"
46
#include "store/naive/store_defs.h"
47
#include "store/naive/node_items.h"
48
#include "store/naive/dataguide.h"
49
#include "store/naive/node_iterators.h"
50
#include "store/naive/simple_item_factory.h"
51
#include "store/naive/simple_iterator_factory.h"
52
#include "store/naive/query_context.h"
53
#include "store/naive/item_iterator.h"
54
#include "store/naive/node_factory.h"
55
#include "store/naive/name_iterator.h"
56
#include "store/naive/document_name_iterator.h"
57
#include "store/naive/pul_primitive_factory.h"
59
#include "util/cxx_util.h"
18
#include "simple_store.h"
19
#include "store_defs.h"
21
#include "simple_collection.h"
22
#include "simple_collection_set.h"
23
#include "simple_item_factory.h"
24
#include "simple_iterator_factory.h"
25
#include "node_factory.h"
26
#include "pul_primitive_factory.h"
27
#include "node_items.h"
29
#include "diagnostics/zorba_exception.h"
30
#include "diagnostics/diagnostic.h"
31
#include <zorba/diagnostic_list.h>
60
33
#include "util/uuid/uuid.h"
61
34
#include "zorbautils/string_util.h"
63
#ifndef ZORBA_NO_FULL_TEXT
64
#include "runtime/full_text/default_tokenizer.h"
65
#include "runtime/full_text/stemmer.h"
66
#endif /* ZORBA_NO_FULL_TEXT */
130
67
********************************************************************************/
131
68
void SimpleStore::init()
133
SYNC_CODE(AutoLock lock(getGlobalLock(), Lock::WRITE);)
135
//zorba::zstring zstr("foo");
136
//zorba::zstring_p pstr;
137
//zorba::zstring_b bstr;
139
if (theNumUsers == 0)
141
// This initializes the libxml2 library and checks potential ABI mismatches
142
// between the version it was compiled for and the actual shared library used.
143
// Calling its init is done here because we also want to free it at the end,
144
// i.e. when the store is shutdown
147
store::Properties::load (0, NULL);
150
theCollectionCounter = 1;
153
theNamespacePool = new StringPool(NAMESPACE_POOL_SIZE);
155
theNamespacePool->insertc("", theEmptyNs);
156
theNamespacePool->insertc(XS_URI, theXmlSchemaNs);
158
theQNamePool = new QNamePool(QNamePool::MAX_CACHE_SIZE, theNamespacePool);
160
// createItemFactory uses theNamespacePool and theQNamePool
161
// they have to be created before this function is called
162
theItemFactory = createItemFactory();
166
theIteratorFactory = new SimpleIteratorFactory();
168
theNodeFactory = createNodeFactory();
170
thePULFactory = createPULPrimitiveFactory();
172
theTraceLevel = store::Properties::instance()->storeTraceLevel();
174
theCollections = createCollectionSet();
176
StoreManagerImpl::theStore = this;
183
/*******************************************************************************
185
********************************************************************************/
186
void SimpleStore::initTypeNames()
188
const char* ns = XS_URI;
189
BasicItemFactory* f = theItemFactory;
191
theSchemaTypeNames.resize(XS_LAST);
193
f->createQName(theSchemaTypeNames[XS_UNTYPED], ns, "xs", "untyped");
194
f->createQName(theSchemaTypeNames[XS_ANY], ns, "xs", "anyType");
196
f->createQName(theSchemaTypeNames[XS_ANY_SIMPLE], ns, "xs", "anySimpleType");
198
f->createQName(theSchemaTypeNames[XS_ANY_ATOMIC], ns, "xs", "anyAtomicType");
200
f->createQName(theSchemaTypeNames[XS_UNTYPED_ATOMIC], ns, "xs", "untypedAtomic");
202
f->createQName(theSchemaTypeNames[XS_ANY_URI], ns, "xs", "anyURI");
204
f->createQName(theSchemaTypeNames[XS_QNAME], ns, "xs", "QName");
206
f->createQName(theSchemaTypeNames[XS_NOTATION], ns, "xs", "NOTATION");
208
f->createQName(theSchemaTypeNames[XS_STRING], ns, "xs", "string");
209
f->createQName(theSchemaTypeNames[XS_NORMALIZED_STRING], ns, "xs", "normalizedString");
210
f->createQName(theSchemaTypeNames[XS_TOKEN], ns, "xs", "token");
211
f->createQName(theSchemaTypeNames[XS_NMTOKEN], ns, "xs", "NMTOKEN");
212
f->createQName(theSchemaTypeNames[XS_LANGUAGE], ns, "xs", "language");
213
f->createQName(theSchemaTypeNames[XS_NAME], ns, "xs", "Name");
214
f->createQName(theSchemaTypeNames[XS_NCNAME], ns, "xs", "NCName");
215
f->createQName(theSchemaTypeNames[XS_ID], ns, "xs", "ID");
216
f->createQName(theSchemaTypeNames[XS_IDREF], ns, "xs", "IDREF");
217
f->createQName(theSchemaTypeNames[XS_ENTITY], ns, "xs", "ENTITY");
219
f->createQName(theSchemaTypeNames[XS_DATETIME], ns, "xs", "dateTime");
220
f->createQName(theSchemaTypeNames[XS_DATE], ns, "xs", "date");
221
f->createQName(theSchemaTypeNames[XS_TIME], ns, "xs", "time");
222
f->createQName(theSchemaTypeNames[XS_GYEAR_MONTH], ns, "xs", "gYearMonth");
223
f->createQName(theSchemaTypeNames[XS_GYEAR], ns, "xs", "gYear");
224
f->createQName(theSchemaTypeNames[XS_GMONTH_DAY], ns, "xs", "gMonthDay");
225
f->createQName(theSchemaTypeNames[XS_GDAY], ns, "xs", "gDay");
226
f->createQName(theSchemaTypeNames[XS_GMONTH], ns, "xs", "gMonth");
228
f->createQName(theSchemaTypeNames[XS_DURATION], ns, "xs", "duration");
229
f->createQName(theSchemaTypeNames[XS_DT_DURATION], ns, "xs", "dayTimeDuration");
230
f->createQName(theSchemaTypeNames[XS_YM_DURATION], ns, "xs", "yearMonthDuration");
232
f->createQName(theSchemaTypeNames[XS_FLOAT], ns, "xs", "float");
233
f->createQName(theSchemaTypeNames[XS_DOUBLE], ns, "xs", "double");
234
f->createQName(theSchemaTypeNames[XS_DECIMAL], ns, "xs", "decimal");
235
f->createQName(theSchemaTypeNames[XS_INTEGER], ns, "xs", "integer");
236
f->createQName(theSchemaTypeNames[XS_NON_POSITIVE_INTEGER], ns, "xs", "nonPositiveInteger");
237
f->createQName(theSchemaTypeNames[XS_NON_NEGATIVE_INTEGER], ns, "xs", "nonNegativeInteger");
238
f->createQName(theSchemaTypeNames[XS_NEGATIVE_INTEGER], ns, "xs", "negativeInteger");
239
f->createQName(theSchemaTypeNames[XS_POSITIVE_INTEGER], ns, "xs", "positiveInteger");
241
f->createQName(theSchemaTypeNames[XS_LONG], ns, "xs", "long");
242
f->createQName(theSchemaTypeNames[XS_INT], ns, "xs", "int");
243
f->createQName(theSchemaTypeNames[XS_SHORT], ns, "xs", "short");
244
f->createQName(theSchemaTypeNames[XS_BYTE], ns, "xs", "byte");
245
f->createQName(theSchemaTypeNames[XS_UNSIGNED_LONG], ns, "xs", "unsignedLong");
246
f->createQName(theSchemaTypeNames[XS_UNSIGNED_INT], ns, "xs", "unsignedInt");
247
f->createQName(theSchemaTypeNames[XS_UNSIGNED_SHORT], ns, "xs", "unsignedShort");
248
f->createQName(theSchemaTypeNames[XS_UNSIGNED_BYTE], ns, "xs", "unsignedByte");
250
f->createQName(theSchemaTypeNames[XS_BASE64BINARY], ns, "xs", "base64Binary");
251
f->createQName(theSchemaTypeNames[XS_HEXBINARY], ns, "xs", "hexBinary");
252
f->createQName(theSchemaTypeNames[XS_BOOLEAN], ns, "xs", "boolean");
254
f->createQName(theSchemaTypeNames[ZXSE_ERROR], ZXSE_URI, "zxse", "error");
255
f->createQName(theSchemaTypeNames[ZXSE_TUPLE], ZXSE_URI, "zxse", "tuple");
257
for (ulong i = 0; i < XS_LAST; ++i)
259
theSchemaTypeCodes[theSchemaTypeNames[i].getp()] = static_cast<SchemaTypeCode>(i);
264
/*******************************************************************************
266
********************************************************************************/
70
theCollectionCounter = 1;
267
76
void SimpleStore::shutdown(bool soft)
269
SYNC_CODE(AutoLock lock(getGlobalLock(), Lock::WRITE);)
271
if (theNumUsers == 0)
276
if (theNumUsers == 0 || soft == false)
78
Store::shutdown(soft);
80
if (theNumUsers == 0 || soft == false)
282
if (theCollections != NULL)
284
theCollections->clear();
285
destroyCollectionSet(theCollections);
286
theCollections = NULL;
289
theDocuments.clear();
291
if (thePULFactory != NULL)
293
destroyPULPrimitiveFactory(thePULFactory);
294
thePULFactory = NULL;
297
if (theNodeFactory != NULL)
299
destroyNodeFactory(theNodeFactory);
300
theNodeFactory = NULL;
303
if (theItemFactory != NULL)
305
destroyItemFactory(theItemFactory);
306
theItemFactory = NULL;
309
if (theQNamePool != NULL)
311
ulong numTypes = (ulong)theSchemaTypeNames.size();
312
for (ulong i = 0; i < numTypes; i++)
313
theSchemaTypeNames[i] = NULL;
319
if (theNamespacePool != NULL)
321
theEmptyNs.~zstring();
322
theXmlSchemaNs.~zstring();
324
delete theNamespacePool;
325
theNamespacePool = NULL;
328
if (theIteratorFactory != NULL)
330
delete theIteratorFactory;
331
theIteratorFactory = NULL;
334
if (theNodeFactory != NULL)
336
delete theNodeFactory;
337
theNodeFactory = NULL;
340
82
if (theNodeToReferencesMap.size() > 0)
342
84
NodeRefMap::iterator iter = theNodeToReferencesMap.begin();
469
223
/*******************************************************************************
470
create a tree id for a new tree that does not belong to any collection.
471
********************************************************************************/
472
ulong SimpleStore::createTreeId()
474
SYNC_CODE(AutoMutex lock(&theTreeCounterMutex);)
475
return theTreeCounter++;
479
/*******************************************************************************
481
********************************************************************************/
482
XmlLoader* SimpleStore::getXmlLoader(XQueryDiagnostics* aXQueryDiagnostics,
483
const store::LoadProperties& loadProperties)
485
if (loadProperties.getEnableExtParsedEntity())
486
return new FragmentXmlLoader(theItemFactory,
488
store::Properties::instance()->buildDataguide());
489
else if (loadProperties.getEnableDtd())
490
return new DtdXmlLoader(theItemFactory,
492
store::Properties::instance()->buildDataguide(),
493
loadProperties.getEnableExtParsedEntity());
495
return new FastXmlLoader(theItemFactory,
497
store::Properties::instance()->buildDataguide());
501
/*******************************************************************************
502
Create an index with a given URI and return an rchandle to the index object.
503
If an index with the given URI exists already and the index we want to create
504
is not a temporary one, raise an error.
505
********************************************************************************/
506
store::Index_t SimpleStore::createIndex(
507
const store::Item_t& qname,
508
const store::IndexSpecification& spec,
509
store::Iterator* sourceIter)
511
store::Item* qname2 = const_cast<store::Item*>(qname.getp());
512
store::Index_t index;
514
if (!spec.theIsTemp && theIndices.get(qname.getp(), index))
516
throw ZORBA_EXCEPTION(zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
517
ERROR_PARAMS(qname->getStringValue()));
520
if (spec.theIsGeneral && spec.theIsSorted)
522
index = new GeneralTreeIndex(qname, spec);
523
populateGeneralIndex(index, sourceIter, spec.getNumColumns());
525
else if (spec.theIsSorted)
527
index = new ValueTreeIndex(qname, spec);
528
populateValueIndex(index, sourceIter, spec.getNumColumns());
530
else if (spec.theIsGeneral)
532
index = new GeneralHashIndex(qname, spec);
533
populateGeneralIndex(index, sourceIter, spec.getNumColumns());
537
index = new ValueHashIndex(qname, spec);
538
populateValueIndex(index, sourceIter, spec.getNumColumns());
543
theIndices.insert(qname2, index);
550
/*******************************************************************************
552
********************************************************************************/
553
void SimpleStore::populateValueIndex(
554
const store::Index_t& aIndex,
555
store::Iterator* aSourceIter,
561
store::Item_t domainItem;
562
store::IndexKey* key = NULL;
564
ValueIndex* index = static_cast<ValueIndex*>(aIndex.getp());
570
while (aSourceIter->next(domainItem))
572
if (domainItem->isNode() &&
573
domainItem->getCollection() == NULL &&
574
!index->isTemporary())
576
RAISE_ERROR_NO_LOC(zerr::ZDDY0020_INDEX_DOMAIN_NODE_NOT_IN_COLLECTION,
577
ERROR_PARAMS(index->getName()->getStringValue()));
581
key = new store::IndexKey(aNumColumns);
583
for (ulong i = 0; i < aNumColumns; ++i)
585
if (!aSourceIter->next((*key)[i]))
587
// The source iter is a ValueIndexEntryBuilderIterator, whose next()
588
// method is guaranteed to return true exactly once. The result from
589
// this single successful next() may be a NULL item.
590
RAISE_ERROR_NO_LOC(zerr::ZXQP0003_INTERNAL_ERROR,
591
ERROR_PARAMS(ZED(IncompleteKeyInIndexBuild)));
595
index->insert(key, domainItem);
603
aSourceIter->close();
610
aSourceIter->close();
614
/*******************************************************************************
616
********************************************************************************/
617
void SimpleStore::populateGeneralIndex(
618
const store::Index_t& idx,
619
store::Iterator* sourceIter,
622
store::Item_t domainNode;
623
store::Item_t firstKeyItem;
624
store::Item_t keyItem;
626
GeneralIndex* index = static_cast<GeneralIndex*>(idx.getp());
632
if (sourceIter->next(domainNode))
636
assert(domainNode->isNode());
637
assert(keyItem == NULL);
639
// Compute the keys associated with the current domain node. Note: We
640
// must check whether the domain node has more than one key, before we
641
// do any insertions in the index.
644
if (domainNode->getCollection() == NULL && !index->isTemporary())
646
RAISE_ERROR_NO_LOC(zerr::ZDDY0020_INDEX_DOMAIN_NODE_NOT_IN_COLLECTION,
647
ERROR_PARAMS(index->getName()->getStringValue()));
650
// Compute 1st key, or next domain node
651
more = sourceIter->next(firstKeyItem);
653
// If current node has no keys, put it in the "null" entry and continue
654
// with the next domain node, if nay.
655
if (!more || firstKeyItem->isNode())
657
index->insert(keyItem, domainNode);
659
domainNode.transfer(firstKeyItem);
663
// Compute 2nd key, or next domain node
664
more = sourceIter->next(keyItem);
666
// If current domain node has exactly 1 key, insert it in the index
667
// and continue with next domain node, if any.
668
if (!more || keyItem->isNode())
670
index->insert(firstKeyItem, domainNode);
672
domainNode.transfer(keyItem);
676
// Current domain node has at least 2 keys. So insert them in the index.
677
// Note: we have to copy the domainNode rchandle because index->insert()
678
// will transfer the given node.
679
index->setMultiKey();
681
store::Item_t node = domainNode;
682
index->insert(firstKeyItem, node);
684
index->insert(keyItem, node);
686
// Compute next keys or next domain node.
687
while ((more = sourceIter->next(keyItem)))
689
if (keyItem->isNode())
691
domainNode.transfer(keyItem);
696
index->insert(keyItem, node);
712
/*******************************************************************************
713
Refreshes an index with a given URI and return an rchandle to the index object.
714
If an index with the given URI exists already and the index we want to create
715
is not a temporary one, raise an error.
716
********************************************************************************/
717
store::Index_t SimpleStore::refreshIndex(
718
const store::Item_t& qname,
719
const store::IndexSpecification& spec,
720
store::Iterator* sourceIter)
722
store::Index_t index;
723
store::Item* non_const_items = const_cast<store::Item*>(qname.getp());
725
if (!theIndices.get(non_const_items, index))
727
throw ZORBA_EXCEPTION(
728
zerr::ZSTR0002_INDEX_DOES_NOT_EXIST,
729
ERROR_PARAMS( qname->getStringValue() )
737
createIndex(qname, index->getSpecification(), sourceIter);
748
/*******************************************************************************
750
********************************************************************************/
751
void SimpleStore::addIndex(store::Index_t& index)
756
store::Item* qname = const_cast<store::Item*>(index->getName());
758
theIndices.insert(qname, index);
762
/*******************************************************************************
764
********************************************************************************/
765
store::Index* SimpleStore::getIndex(const store::Item* qname)
770
store::Item* qname2 = const_cast<store::Item*>(qname);
771
store::Index_t index;
773
if (theIndices.get(qname2, index))
780
/*******************************************************************************
782
********************************************************************************/
783
void SimpleStore::deleteIndex(const store::Item* qname)
788
store::Item* qname2 = const_cast<store::Item*>(qname);
790
theIndices.erase(qname2);
794
/*******************************************************************************
796
********************************************************************************/
797
store::Iterator_t SimpleStore::listIndexNames()
799
return new NameIterator<IndexSet>(theIndices);
803
/*******************************************************************************
805
********************************************************************************/
806
store::IC_t SimpleStore::activateIC(
807
const store::Item_t& icQName,
808
const store::Item_t& collectionQName,
811
ZORBA_ASSERT(icQName != NULL);
813
store::Item* qname = icQName.getp();
817
if (theICs.get(qname, ic))
819
return ic; // already activated => noop
822
ic = new ICCollectionImpl(icQName, collectionQName);
824
theICs.insert(qname, ic);
831
/*******************************************************************************
833
********************************************************************************/
834
store::IC_t SimpleStore::activateForeignKeyIC(
835
const store::Item_t& icQName,
836
const store::Item_t& fromCollectionQName,
837
const store::Item_t& toCollectionQName,
840
ZORBA_ASSERT(icQName != NULL);
842
store::Item* qname = const_cast<store::Item*>(icQName.getp());
846
if (theICs.get(qname, ic))
848
return ic; // already activated => noop
851
ic = new ICForeignKeyImpl(qname, fromCollectionQName, toCollectionQName);
853
theICs.insert(qname, ic);
861
SimpleStore::deactivateIC(const store::Item_t& icQName,
864
ZORBA_ASSERT(icQName != NULL);
868
if (!theICs.get(icQName.getp(), ic))
870
return ic; // already deactivated in the same PUL => noop
873
theICs.erase(icQName.getp());
879
store::Iterator_t SimpleStore::listActiveICNames()
881
return new NameIterator<ICSet>(theICs);
885
store::IC* SimpleStore::getIC(const store::Item* icQName)
887
store::Item* qname = const_cast<store::Item*>(icQName);
889
theICs.get(qname, ic);
895
/*******************************************************************************
897
********************************************************************************/
899
SimpleStore::getMap(const store::Item* aQName) const
901
store::Item* lQName = const_cast<store::Item*>(aQName);
902
store::Index_t lIndex;
903
const_cast<IndexSet*>(&theHashMaps)->get(lQName, lIndex);
905
return lIndex.getp();
909
/*******************************************************************************
911
********************************************************************************/
912
store::Iterator_t SimpleStore::listMapNames()
914
return new NameIterator<IndexSet>(theHashMaps);
918
/*******************************************************************************
919
224
Create a collection with a given QName and return an rchandle to the new
920
225
collection object. If a collection with the given QName exists already, raise
953
258
/*******************************************************************************
955
********************************************************************************/
956
void SimpleStore::addCollection(store::Collection_t& collection)
958
const store::Item* lName = collection->getName();
960
bool inserted = theCollections->insert(lName, collection);
964
throw ZORBA_EXCEPTION(zerr::ZSTR0008_COLLECTION_ALREADY_EXISTS,
965
ERROR_PARAMS(lName->getStringValue()));
970
/*******************************************************************************
971
Return an rchandle to the Collection object corresponding to the given QName,
972
or NULL if there is no collection with that QName.
973
********************************************************************************/
974
store::Collection_t SimpleStore::getCollection(
975
const store::Item* aName,
976
bool aDynamicCollection)
981
store::Collection_t collection;
982
if (theCollections->get(aName, collection, aDynamicCollection))
993
/*******************************************************************************
994
Delete the collection with the given QName. If there is no collection with
995
that QName, this method is a NOOP.
996
********************************************************************************/
997
void SimpleStore::deleteCollection(
998
const store::Item* aName,
999
bool aDynamicCollection)
1004
if (!theCollections->remove(aName, aDynamicCollection))
1006
throw ZORBA_EXCEPTION(zerr::ZSTR0009_COLLECTION_NOT_FOUND,
1007
ERROR_PARAMS(aName->getStringValue()));
1012
/*******************************************************************************
1013
Returns an iterator that lists the QName's of all the available collections.
1014
********************************************************************************/
1015
store::Iterator_t SimpleStore::listCollectionNames(bool aDynamicCollections)
1017
return theCollections->names(aDynamicCollections);
1021
/*******************************************************************************
1023
********************************************************************************/
1024
store::Item_t SimpleStore::loadDocument(
1025
const zstring& baseUri,
1026
const zstring& docUri,
1027
std::istream& stream,
1028
const store::LoadProperties& loadProperties)
1032
if (!docUri.empty())
1033
urib.wrap_memory(docUri.data(), docUri.size());
1036
bool found = theDocuments.get(urib, root);
1043
XQueryDiagnostics lXQueryDiagnostics;
1044
std::auto_ptr<XmlLoader> loader(getXmlLoader(&lXQueryDiagnostics, loadProperties));
1046
root = loader->loadXml(baseUri, docUri, stream);
1048
if (!lXQueryDiagnostics.errors().empty())
1050
lXQueryDiagnostics.errors().front()->polymorphic_throw();
1053
if (root != NULL && loadProperties.getStoreDocument())
1054
theDocuments.insert(urib, root);
1060
/*******************************************************************************
1062
Param stream is a heap pointer to an input stream. This is to be deallocated
1064
********************************************************************************/
1065
store::Item_t SimpleStore::loadDocument(
1066
const zstring& baseUri,
1067
const zstring& docUri,
1068
std::istream* stream,
1069
const store::LoadProperties& loadProperties)
1071
store::Item_t docitem;
1074
//do full loading for now
1075
docitem = loadDocument(baseUri, docUri, *stream, loadProperties);
1086
/*******************************************************************************
1087
Add the given node with the given uri to the store. Essentially, this method
1088
establishes an association between a uri and a node. If the given uri is
1089
already associated to another node, the method raises an error. If the given
1090
uri is already associated to the given node, this method is a noop.
1091
********************************************************************************/
1092
void SimpleStore::addNode(const zstring& uri, const store::Item_t& node)
1094
ZORBA_ASSERT(!uri.empty());
1096
if (node == NULL || !node->isNode())
1098
RAISE_ERROR_NO_LOC(zerr::ZAPI0021_ITEM_TO_LOAD_IS_NOT_NODE, ERROR_PARAMS(uri));
1101
XmlNode_t root = reinterpret_cast<XmlNode*>(node.getp());
1103
bool inserted = theDocuments.insert(uri, root);
1105
if (!inserted && node.getp() != root.getp())
1107
RAISE_ERROR_NO_LOC(zerr::ZAPI0020_DOCUMENT_ALREADY_EXISTS, ERROR_PARAMS(uri));
1110
ZORBA_FATAL(node.getp() == root.getp(), "");
1114
/*******************************************************************************
1115
Return an rchandle to an iterator over the set of documents in the store
1116
********************************************************************************/
1117
store::Iterator_t SimpleStore::getDocumentNames() const
1119
return new DocumentNameIterator<DocumentSet>(theDocuments);
1123
/*******************************************************************************
1124
Return an rchandle to the root node of the document corresponding to the given
1125
URI, or NULL if there is no document with that URI.
1126
********************************************************************************/
1127
store::Item_t SimpleStore::getDocument(const zstring& uri)
1134
bool found = theDocuments.get(uri, root);
1143
/*******************************************************************************
1144
Delete the document with the given URI. If there is no document with that
1145
URI, this method is a NOOP.
1146
********************************************************************************/
1147
void SimpleStore::deleteDocument(const zstring& uri)
1152
theDocuments.erase(uri);
1156
/*******************************************************************************
1157
Delete all the documents.
1158
********************************************************************************/
1159
void SimpleStore::deleteAllDocuments()
1161
theDocuments.clear();
1165
/*******************************************************************************
1167
********************************************************************************/
1169
SimpleStore::createHashMap(
1170
const store::Item_t& aQName,
1171
const store::IndexSpecification& aSpec)
1173
store::Index_t lIndex;
1175
if (theHashMaps.get(aQName.getp(), lIndex))
1177
throw ZORBA_EXCEPTION(
1178
zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
1179
ERROR_PARAMS( aQName->getStringValue() )
1183
lIndex = new ValueHashIndex(aQName, aSpec);
1191
/*******************************************************************************
1193
********************************************************************************/
1195
SimpleStore::destroyHashMap(const store::Item_t& aQName)
1197
store::Index_t lIndex;
1198
if (!theHashMaps.get(aQName.getp(), lIndex))
1200
throw ZORBA_EXCEPTION(
1201
zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
1202
ERROR_PARAMS( aQName->getStringValue() )
1205
theHashMaps.erase(aQName.getp());
1210
/*******************************************************************************
1212
********************************************************************************/
1214
SimpleStore::getHashMap(const store::Item_t& aQName) const
1216
store::Index_t lIndex;
1217
if (const_cast<IndexSet*>(&theHashMaps)->get(aQName.getp(), lIndex))
1228
/*******************************************************************************
1230
********************************************************************************/
1232
SimpleStore::addHashMap(const store::Index_t& aIndex)
1234
store::Item* lName = aIndex->getName();
1235
store::Index_t lIndex = aIndex;
1236
theHashMaps.insert(lName, lIndex);
1239
/*******************************************************************************
1240
Compare two nodes, based on their node id. Return -1 if node1 < node2, 0, if
1241
node1 == node2, or 1 if node1 > node2.
1242
********************************************************************************/
1243
short SimpleStore::compareNodes(store::Item* node1, store::Item* node2) const
1245
ZORBA_FATAL(node1->isNode(), "");
1246
ZORBA_FATAL(node2->isNode(), "");
1251
XmlNode* n1 = static_cast<XmlNode*>(node1);
1252
XmlNode* n2 = static_cast<XmlNode*>(node2);
1254
return (short)n1->compare2(n2);
1258
/*******************************************************************************
1259
Sorts the items of the passed iterator
1261
@param iterator to sort
1262
@param ascendent true for ascendent and false for descendant
1263
@param duplicate duplicate elemination should be applied
1264
@return iterator which produces the sorted items
1265
********************************************************************************/
1266
store::Iterator_t SimpleStore::sortNodes(
1267
store::Iterator* input,
1269
bool duplicateElemination,
1273
return new StoreNodeSortOrAtomicIterator(input, ascendent, duplicateElemination);
1275
return new StoreNodeSortIterator(input, ascendent, duplicateElemination);
1279
/*******************************************************************************
1280
Create an iterator that eliminates the duplicate nodes in the set of items
1281
which is produced by the passed iterator
1282
********************************************************************************/
1283
store::Iterator_t SimpleStore::distinctNodes(
1284
store::Iterator* input,
1288
return new StoreNodeDistinctOrAtomicIterator(input);
1290
return new StoreNodeDistinctIterator(input, false);
1294
/*******************************************************************************
1295
Create an iterator that checks for duplicate nodes in the set of nodes which
1296
is produced by the passed iterator, and raises an error if any duplicates
1297
are found. If no duplicates are found, the iterator simply passes on the
1298
input nodes to its consumer.
1299
********************************************************************************/
1300
store::Iterator_t SimpleStore::checkDistinctNodes(store::Iterator* input)
1302
return new StoreNodeDistinctIterator(input, true);
1306
/*******************************************************************************
1307
Computes the Structural Reference for the given node.
1308
********************************************************************************/
1309
bool SimpleStore::getStructuralInformation(
1310
store::Item_t& result,
1311
const store::Item* node)
1314
const OrdPathNode* n = static_cast<const OrdPathNode*>(node);
1316
return theItemFactory->createStructuralAnyURI(result,
1317
n->getCollectionId(),
1322
if (node->getNodeKind() == store::StoreConsts::textNode)
1325
const TextNode* n = static_cast<const TextNode*>(node);
1326
n->getOrdPath(ordPath);
1328
return theItemFactory->createStructuralAnyURI(result,
1329
n->getCollectionId(),
1331
store::StoreConsts::textNode,
1336
const OrdPathNode* n = static_cast<const OrdPathNode*>(node);
1338
return theItemFactory->createStructuralAnyURI(result,
1339
n->getCollectionId(),
1348
/*******************************************************************************
1349
259
Computes the reference of the given node.
1351
261
@param node XDM node
1352
262
@return the identifier as an item of type xs:anyURI
1353
263
********************************************************************************/
1354
bool SimpleStore::getNodeReference(store::Item_t& result, store::Item* node)
264
bool SimpleStore::getNodeReference(store::Item_t& result, const store::Item* node)
1356
XmlNode* xmlNode = static_cast<XmlNode*>(node);
266
const XmlNode* xmlNode = static_cast<const XmlNode*>(node);
1358
268
if (xmlNode->haveReference())
1452
/*******************************************************************************
1454
********************************************************************************/
1455
bool SimpleStore::getPathInfo(
1456
const store::Item* docUriItem,
1457
std::vector<const store::Item*>& contextPath,
1458
std::vector<const store::Item*>& relativePath,
1464
docUriItem->getStringValue2(docUri);
1466
XmlNode_t docRoot = BASE_NODE(getDocument(docUri));
1468
if (docRoot == NULL)
1472
GuideNode* guideRoot = docRoot->getDataGuide();
1477
guideRoot->getPathInfo(contextPath, relativePath, isAttrPath, found, unique);
1483
/*******************************************************************************
1484
Creates a new TempSeq. The instance can be used, e.g. for variable bindings
1486
@param iterator The source for the XMDInstance
1487
@param lazy Hint for the store. If possible a XMDInstance should be
1488
evaluated lazily. For XQueryP it might be necassary to set
1490
********************************************************************************/
1491
TempSeq_t SimpleStore::createTempSeq(const store::Iterator_t& iterator, bool lazy)
1495
//tempSeq = new SimpleTempSeq(iterator, copyNodes);
1496
return new SimpleLazyTempSeq(iterator);
1500
return new SimpleTempSeq(iterator);
1505
/*******************************************************************************
1506
Creates an empty TempSeq.
1507
********************************************************************************/
1508
TempSeq_t SimpleStore::createTempSeq(bool lazy)
1512
return new SimpleLazyTempSeq();
1516
return new SimpleTempSeq();
1521
/*******************************************************************************
1522
Creates a temp seq initialized by the given vector.
1523
@param item_v - The vector to use to initialize the seq.
1524
********************************************************************************/
1525
TempSeq_t SimpleStore::createTempSeq(std::vector<store::Item_t>& items)
1527
return new SimpleTempSeq(items);
1531
/*******************************************************************************
1532
Creates a temp seq initialized by the given item.
1533
********************************************************************************/
1534
TempSeq_t SimpleStore::createTempSeq(store::Item_t& item)
1536
return new SimpleTempSeq(item);
1540
#ifndef ZORBA_NO_FULL_TEXT
1541
void SimpleStore::setStemmerProvider( internal::StemmerProvider const *p )
1543
theStemmerProvider = p;
1547
void SimpleStore::setTokenizerProvider( TokenizerProvider const *p )
1549
theTokenizerProvider = p;
1553
internal::StemmerProvider const* SimpleStore::getStemmerProvider() const
1555
return theStemmerProvider ?
1556
theStemmerProvider : &internal::StemmerProvider::get_default();
1560
TokenizerProvider const* SimpleStore::getTokenizerProvider() const
1562
return theTokenizerProvider ?
1563
theTokenizerProvider : &default_tokenizer_provider();
1565
#endif /* ZORBA_NO_FULL_TEXT */
1567
} // namespace store
362
} // namespace simplestore
1568
363
} // namespace zorba
1569
/* vim:set et sw=2 ts=2: */