~zorba-coders/zorba/bugs-912586-912593-912722

« back to all changes in this revision

Viewing changes to src/store/naive/simple_store.cpp

  • Committer: Cezar Andrei
  • Date: 2012-03-28 15:42:12 UTC
  • mfrom: (10606.1.129 zorba)
  • Revision ID: cezar.lp@cezarandrei.com-20120328154212-jh2heq49xcqjppce
Merge from trunck and resolve ChangeLog conflict.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 */
16
16
#include "stdafx.h"
17
17
 
18
 
#include <iostream>
19
 
#include <climits>
20
 
#include <memory>
21
 
 
22
 
#include <libxml/parser.h>
23
 
 
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"
30
 
 
31
 
#include "store/api/pul.h"
32
 
 
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"
58
 
 
59
 
#include "util/cxx_util.h"
 
18
#include "simple_store.h"
 
19
#include "store_defs.h"
 
20
 
 
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"
 
28
 
 
29
#include "diagnostics/zorba_exception.h"
 
30
#include "diagnostics/diagnostic.h"
 
31
#include <zorba/diagnostic_list.h>
 
32
 
60
33
#include "util/uuid/uuid.h"
61
34
#include "zorbautils/string_util.h"
62
35
 
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 */
67
 
 
68
36
namespace zorba
69
37
{
70
38
 
73
41
 
74
42
typedef rchandle<store::TempSeq> TempSeq_t;
75
43
 
76
 
 
77
 
/*******************************************************************************
78
 
  SimpleStore static data
79
 
********************************************************************************/
80
 
const ulong SimpleStore::NAMESPACE_POOL_SIZE = 128;
81
 
 
82
 
const char* SimpleStore::XS_URI = "http://www.w3.org/2001/XMLSchema";
83
 
const char* SimpleStore::XML_URI = "http://www.w3.org/2001/XML/1998/namespace";
84
 
const char* SimpleStore::ZXSE_URI = "http://www.zorba-xquery.com/zorba/schema-extensions";
85
 
 
86
 
const ulong SimpleStore::XML_URI_LEN = sizeof(SimpleStore::XML_URI);
87
 
 
88
 
 
89
44
/*******************************************************************************
90
45
 
91
46
********************************************************************************/
92
47
SimpleStore::SimpleStore()
93
48
  :
94
 
  theNumUsers(0),
95
 
  theUriCounter(0),
96
49
  theCollectionCounter(1),
97
50
  theTreeCounter(1),
98
 
  theNamespacePool(NULL),
99
 
  theQNamePool(NULL),
100
 
  theItemFactory(NULL),
101
 
  theIteratorFactory(NULL),
102
 
  theNodeFactory(NULL),
103
 
  thePULFactory(NULL),
104
 
  theDocuments(CollectionSet::DEFAULT_COLLECTION_MAP_SIZE, true),
105
 
  theCollections(0),
106
 
  theIndices(0, NULL, CollectionSet::DEFAULT_COLLECTION_MAP_SIZE, true),
107
 
  theICs(0, NULL, CollectionSet::DEFAULT_COLLECTION_MAP_SIZE, true),
108
 
  theHashMaps(0, NULL, CollectionSet::DEFAULT_COLLECTION_MAP_SIZE, true),
109
 
  theTraceLevel(0),
110
51
  theNodeToReferencesMap(128, true)
111
 
#ifndef ZORBA_NO_FULL_TEXT
112
 
  , theStemmerProvider( nullptr )
113
 
  , theTokenizerProvider( nullptr )
114
 
#endif /* ZORBA_NO_FULL_TEXT */
115
52
{
116
53
}
117
54
 
130
67
********************************************************************************/
131
68
void SimpleStore::init()
132
69
{
133
 
  SYNC_CODE(AutoLock lock(getGlobalLock(), Lock::WRITE);)
134
 
 
135
 
  //zorba::zstring zstr("foo");
136
 
  //zorba::zstring_p pstr;
137
 
  //zorba::zstring_b bstr;
138
 
 
139
 
  if (theNumUsers == 0)
140
 
  {
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
145
 
    LIBXML_TEST_VERSION
146
 
 
147
 
    store::Properties::load (0, NULL);
148
 
 
149
 
    theUriCounter = 0;
150
 
    theCollectionCounter = 1;
151
 
    theTreeCounter = 1;
152
 
 
153
 
    theNamespacePool = new StringPool(NAMESPACE_POOL_SIZE);
154
 
 
155
 
    theNamespacePool->insertc("", theEmptyNs);
156
 
    theNamespacePool->insertc(XS_URI, theXmlSchemaNs);
157
 
 
158
 
    theQNamePool = new QNamePool(QNamePool::MAX_CACHE_SIZE, theNamespacePool);
159
 
 
160
 
    // createItemFactory uses theNamespacePool and theQNamePool
161
 
    // they have to be created before this function is called
162
 
    theItemFactory = createItemFactory();
163
 
 
164
 
    initTypeNames();
165
 
 
166
 
    theIteratorFactory = new SimpleIteratorFactory();
167
 
 
168
 
    theNodeFactory = createNodeFactory();
169
 
 
170
 
    thePULFactory = createPULPrimitiveFactory();
171
 
 
172
 
    theTraceLevel = store::Properties::instance()->storeTraceLevel();
173
 
 
174
 
    theCollections = createCollectionSet();
175
 
 
176
 
    StoreManagerImpl::theStore = this;
177
 
  }
178
 
 
179
 
  ++theNumUsers;
180
 
}
181
 
 
182
 
 
183
 
/*******************************************************************************
184
 
 
185
 
********************************************************************************/
186
 
void SimpleStore::initTypeNames()
187
 
{
188
 
  const char* ns = XS_URI;
189
 
  BasicItemFactory* f = theItemFactory;
190
 
 
191
 
  theSchemaTypeNames.resize(XS_LAST);
192
 
 
193
 
  f->createQName(theSchemaTypeNames[XS_UNTYPED],        ns, "xs", "untyped");
194
 
  f->createQName(theSchemaTypeNames[XS_ANY],            ns, "xs", "anyType");
195
 
 
196
 
  f->createQName(theSchemaTypeNames[XS_ANY_SIMPLE],     ns, "xs", "anySimpleType");
197
 
 
198
 
  f->createQName(theSchemaTypeNames[XS_ANY_ATOMIC],     ns, "xs", "anyAtomicType");
199
 
 
200
 
  f->createQName(theSchemaTypeNames[XS_UNTYPED_ATOMIC], ns, "xs", "untypedAtomic");
201
 
 
202
 
  f->createQName(theSchemaTypeNames[XS_ANY_URI],        ns, "xs", "anyURI");
203
 
 
204
 
  f->createQName(theSchemaTypeNames[XS_QNAME],          ns, "xs", "QName");
205
 
 
206
 
  f->createQName(theSchemaTypeNames[XS_NOTATION],       ns, "xs", "NOTATION");
207
 
 
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");
218
 
 
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");
227
 
 
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");
231
 
 
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");
240
 
 
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");
249
 
 
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");
253
 
 
254
 
  f->createQName(theSchemaTypeNames[ZXSE_ERROR], ZXSE_URI, "zxse", "error");
255
 
  f->createQName(theSchemaTypeNames[ZXSE_TUPLE], ZXSE_URI, "zxse", "tuple");
256
 
 
257
 
  for (ulong i = 0; i < XS_LAST; ++i)
258
 
  {
259
 
    theSchemaTypeCodes[theSchemaTypeNames[i].getp()] = static_cast<SchemaTypeCode>(i);
260
 
  }
261
 
}
262
 
 
263
 
 
264
 
/*******************************************************************************
265
 
 
266
 
********************************************************************************/
 
70
  theCollectionCounter = 1;
 
71
  theTreeCounter = 1;
 
72
 
 
73
  Store::init();
 
74
}
 
75
 
267
76
void SimpleStore::shutdown(bool soft)
268
77
{
269
 
  SYNC_CODE(AutoLock lock(getGlobalLock(), Lock::WRITE);)
270
 
 
271
 
  if (theNumUsers == 0)
272
 
    return;
273
 
 
274
 
  --theNumUsers;
275
 
 
276
 
  if (theNumUsers == 0 || soft == false)
 
78
  Store::shutdown(soft);
 
79
 
 
80
  if (theNumUsers == 0 || soft == false) 
277
81
  {
278
 
    theIndices.clear();
279
 
    theICs.clear();
280
 
    theHashMaps.clear();
281
 
 
282
 
    if (theCollections != NULL)
283
 
    {
284
 
      theCollections->clear();
285
 
      destroyCollectionSet(theCollections);
286
 
      theCollections = NULL;
287
 
    }
288
 
 
289
 
    theDocuments.clear();
290
 
 
291
 
    if (thePULFactory != NULL)
292
 
    {
293
 
      destroyPULPrimitiveFactory(thePULFactory);
294
 
      thePULFactory = NULL;
295
 
    }
296
 
 
297
 
    if (theNodeFactory != NULL)
298
 
    {
299
 
      destroyNodeFactory(theNodeFactory);
300
 
      theNodeFactory = NULL;
301
 
    }
302
 
 
303
 
    if (theItemFactory != NULL)
304
 
    {
305
 
      destroyItemFactory(theItemFactory);
306
 
      theItemFactory = NULL;
307
 
    }
308
 
 
309
 
    if (theQNamePool != NULL)
310
 
    {
311
 
      ulong numTypes = (ulong)theSchemaTypeNames.size();
312
 
      for (ulong i = 0; i < numTypes; i++)
313
 
        theSchemaTypeNames[i] = NULL;
314
 
 
315
 
      delete theQNamePool;
316
 
      theQNamePool = NULL;
317
 
    }
318
 
 
319
 
    if (theNamespacePool != NULL)
320
 
    {
321
 
      theEmptyNs.~zstring();
322
 
      theXmlSchemaNs.~zstring();
323
 
 
324
 
      delete theNamespacePool;
325
 
      theNamespacePool = NULL;
326
 
    }
327
 
 
328
 
    if (theIteratorFactory != NULL)
329
 
    {
330
 
      delete theIteratorFactory;
331
 
      theIteratorFactory = NULL;
332
 
    }
333
 
 
334
 
    if (theNodeFactory != NULL)
335
 
    {
336
 
      delete theNodeFactory;
337
 
      theNodeFactory = NULL;
338
 
    }
339
 
 
340
82
    if (theNodeToReferencesMap.size() > 0)
341
83
    {
342
84
      NodeRefMap::iterator iter = theNodeToReferencesMap.begin();
346
88
        std::cerr << "Reference: " << (*iter).second
347
89
                  << "is still in the nodes to references map" << std::endl;
348
90
      }
349
 
      ZORBA_FATAL(0, theNodeToReferencesMap.size() + 
 
91
      ZORBA_FATAL(0, theNodeToReferencesMap.size() +
350
92
                     " node references still in the nodes to references map");
351
93
    }
352
94
 
356
98
      RefNodeMap::iterator end = theReferencesToNodeMap.end();
357
99
      for (; iter != end; ++iter)
358
100
      {
359
 
        std::cerr << "Reference: " << (*iter).first 
 
101
        std::cerr << "Reference: " << (*iter).first
360
102
                  << "is still in the references to nodes map" << std::endl;
361
103
      }
362
104
      ZORBA_FATAL(0, theReferencesToNodeMap.size() +
363
105
                     " node references still in the references to nodes map");
364
106
    }
365
 
 
366
 
    // do cleanup of the libxml2 library
367
 
    // however, after that, a user will have to call
368
 
    // LIBXML_TEST_VERSION if he wants to use libxml2
369
 
    // beyond the lifecycle of zorba
370
 
    xmlCleanupParser();
371
 
 
372
 
    StoreManagerImpl::theStore = NULL;
373
107
  }
374
108
}
375
109
 
378
112
 
379
113
*******************************************************************************/
380
114
PULPrimitiveFactory*
381
 
SimpleStore::createPULPrimitiveFactory() const
 
115
SimpleStore::createPULFactory() const
382
116
{
383
117
  return new PULPrimitiveFactory();
384
118
}
388
122
 
389
123
*******************************************************************************/
390
124
void
391
 
SimpleStore::destroyPULPrimitiveFactory(PULPrimitiveFactory* f) const
 
125
SimpleStore::destroyPULFactory(PULPrimitiveFactory* f) const
392
126
{
393
127
  delete f;
394
128
}
395
129
 
 
130
 
396
131
/*******************************************************************************
397
132
 
398
133
*******************************************************************************/
399
134
CollectionSet* SimpleStore::createCollectionSet() const
400
135
{
401
 
  return new CollectionSet();
 
136
  return new SimpleCollectionSet();
402
137
}
403
138
 
404
139
 
432
167
/*******************************************************************************
433
168
 
434
169
*******************************************************************************/
435
 
BasicItemFactory* SimpleStore::createItemFactory() const
 
170
store::ItemFactory* SimpleStore::createItemFactory() const
436
171
{
437
172
  return new BasicItemFactory(theNamespacePool, theQNamePool);
438
173
}
441
176
/*******************************************************************************
442
177
 
443
178
*******************************************************************************/
444
 
void SimpleStore::destroyItemFactory(BasicItemFactory* f) const
445
 
{
446
 
  delete f;
447
 
}
448
 
 
449
 
 
450
 
/*******************************************************************************
451
 
 
 
179
void SimpleStore::destroyItemFactory(store::ItemFactory* f) const
 
180
{
 
181
  delete f;
 
182
}
 
183
 
 
184
 
 
185
/*******************************************************************************
 
186
 
 
187
*******************************************************************************/
 
188
store::IteratorFactory* SimpleStore::createIteratorFactory() const
 
189
{
 
190
  return new SimpleIteratorFactory();
 
191
}
 
192
 
 
193
 
 
194
/*******************************************************************************
 
195
 
 
196
*******************************************************************************/
 
197
void SimpleStore::destroyIteratorFactory(store::IteratorFactory* f) const
 
198
{
 
199
  delete f;
 
200
}
 
201
 
 
202
 
 
203
/*******************************************************************************
 
204
  create a tree id for a new tree that does not belong to any collection.
452
205
********************************************************************************/
453
 
store::ItemFactory* SimpleStore::getItemFactory() const
 
206
ulong SimpleStore::createTreeId()
454
207
{
455
 
  return theItemFactory;
 
208
  SYNC_CODE(AutoMutex lock(&theTreeCounterMutex);)
 
209
  return theTreeCounter++;
456
210
}
457
211
 
458
212
 
467
221
 
468
222
 
469
223
/*******************************************************************************
470
 
  create a tree id for a new tree that does not belong to any collection.
471
 
********************************************************************************/
472
 
ulong SimpleStore::createTreeId()
473
 
{
474
 
  SYNC_CODE(AutoMutex lock(&theTreeCounterMutex);)
475
 
  return theTreeCounter++;
476
 
}
477
 
 
478
 
 
479
 
/*******************************************************************************
480
 
 
481
 
********************************************************************************/
482
 
XmlLoader* SimpleStore::getXmlLoader(XQueryDiagnostics* aXQueryDiagnostics,
483
 
    const store::LoadProperties& loadProperties)
484
 
{
485
 
  if (loadProperties.getEnableExtParsedEntity())
486
 
    return new FragmentXmlLoader(theItemFactory,
487
 
                                 aXQueryDiagnostics,
488
 
                                 store::Properties::instance()->buildDataguide());
489
 
  else if (loadProperties.getEnableDtd())
490
 
    return new DtdXmlLoader(theItemFactory,
491
 
                            aXQueryDiagnostics,
492
 
                            store::Properties::instance()->buildDataguide(),
493
 
                            loadProperties.getEnableExtParsedEntity());
494
 
  else
495
 
    return new FastXmlLoader(theItemFactory,
496
 
                             aXQueryDiagnostics,
497
 
                             store::Properties::instance()->buildDataguide());
498
 
}
499
 
 
500
 
 
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)
510
 
{
511
 
  store::Item* qname2 = const_cast<store::Item*>(qname.getp());
512
 
  store::Index_t index;
513
 
 
514
 
  if (!spec.theIsTemp && theIndices.get(qname.getp(), index))
515
 
  {
516
 
    throw ZORBA_EXCEPTION(zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
517
 
    ERROR_PARAMS(qname->getStringValue()));
518
 
  }
519
 
 
520
 
  if (spec.theIsGeneral && spec.theIsSorted)
521
 
  {
522
 
    index = new GeneralTreeIndex(qname, spec);
523
 
    populateGeneralIndex(index, sourceIter, spec.getNumColumns());
524
 
  }
525
 
  else if (spec.theIsSorted)
526
 
  {
527
 
    index = new ValueTreeIndex(qname, spec);
528
 
    populateValueIndex(index, sourceIter, spec.getNumColumns());
529
 
  }
530
 
  else if (spec.theIsGeneral)
531
 
  {
532
 
    index = new GeneralHashIndex(qname, spec);
533
 
    populateGeneralIndex(index, sourceIter, spec.getNumColumns());
534
 
  }
535
 
  else
536
 
  {
537
 
    index = new ValueHashIndex(qname, spec);
538
 
    populateValueIndex(index, sourceIter, spec.getNumColumns());
539
 
  }
540
 
 
541
 
  if (!spec.theIsTemp)
542
 
  {
543
 
    theIndices.insert(qname2, index);
544
 
  }
545
 
 
546
 
  return index;
547
 
}
548
 
 
549
 
 
550
 
/*******************************************************************************
551
 
 
552
 
********************************************************************************/
553
 
void SimpleStore::populateValueIndex(
554
 
    const store::Index_t& aIndex,
555
 
    store::Iterator* aSourceIter,
556
 
    ulong aNumColumns)
557
 
{
558
 
  if (!aSourceIter)
559
 
    return;
560
 
 
561
 
  store::Item_t domainItem;
562
 
  store::IndexKey* key = NULL;
563
 
 
564
 
  ValueIndex* index = static_cast<ValueIndex*>(aIndex.getp());
565
 
 
566
 
  aSourceIter->open();
567
 
 
568
 
  try
569
 
  {
570
 
    while (aSourceIter->next(domainItem))
571
 
    {
572
 
      if (domainItem->isNode() &&
573
 
          domainItem->getCollection() == NULL &&
574
 
          !index->isTemporary())
575
 
      {
576
 
        RAISE_ERROR_NO_LOC(zerr::ZDDY0020_INDEX_DOMAIN_NODE_NOT_IN_COLLECTION,
577
 
        ERROR_PARAMS(index->getName()->getStringValue()));
578
 
      }
579
 
 
580
 
      if (key == NULL)
581
 
        key = new store::IndexKey(aNumColumns);
582
 
 
583
 
      for (ulong i = 0; i < aNumColumns; ++i)
584
 
      {
585
 
        if (!aSourceIter->next((*key)[i]))
586
 
        {
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)));
592
 
        }
593
 
      }
594
 
 
595
 
      index->insert(key, domainItem);
596
 
    }
597
 
  }
598
 
  catch(...)
599
 
  {
600
 
    if (key != NULL)
601
 
      delete key;
602
 
 
603
 
    aSourceIter->close();
604
 
    throw;
605
 
  }
606
 
 
607
 
  if (key != NULL)
608
 
    delete key;
609
 
 
610
 
  aSourceIter->close();
611
 
}
612
 
 
613
 
 
614
 
/*******************************************************************************
615
 
 
616
 
********************************************************************************/
617
 
void SimpleStore::populateGeneralIndex(
618
 
    const store::Index_t& idx,
619
 
    store::Iterator* sourceIter,
620
 
    ulong numColumns)
621
 
{
622
 
  store::Item_t domainNode;
623
 
  store::Item_t firstKeyItem;
624
 
  store::Item_t keyItem;
625
 
 
626
 
  GeneralIndex* index = static_cast<GeneralIndex*>(idx.getp());
627
 
 
628
 
  sourceIter->open();
629
 
 
630
 
  try
631
 
  {
632
 
    if (sourceIter->next(domainNode))
633
 
    {
634
 
      bool more = true;
635
 
 
636
 
      assert(domainNode->isNode());
637
 
      assert(keyItem == NULL);
638
 
 
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.
642
 
      while (more)
643
 
      {
644
 
        if (domainNode->getCollection() == NULL && !index->isTemporary())
645
 
        {
646
 
          RAISE_ERROR_NO_LOC(zerr::ZDDY0020_INDEX_DOMAIN_NODE_NOT_IN_COLLECTION,
647
 
          ERROR_PARAMS(index->getName()->getStringValue()));
648
 
        }
649
 
 
650
 
        // Compute 1st key, or next domain node
651
 
        more = sourceIter->next(firstKeyItem);
652
 
 
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())
656
 
        {
657
 
          index->insert(keyItem, domainNode);
658
 
 
659
 
          domainNode.transfer(firstKeyItem);
660
 
          continue;
661
 
        }
662
 
 
663
 
        // Compute 2nd key, or next domain node
664
 
        more = sourceIter->next(keyItem);
665
 
 
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())
669
 
        {
670
 
          index->insert(firstKeyItem, domainNode);
671
 
 
672
 
          domainNode.transfer(keyItem);
673
 
          continue;
674
 
        }
675
 
 
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();
680
 
 
681
 
        store::Item_t node = domainNode;
682
 
        index->insert(firstKeyItem, node);
683
 
        node = domainNode;
684
 
        index->insert(keyItem, node);
685
 
 
686
 
        // Compute next keys or next domain node.
687
 
        while ((more = sourceIter->next(keyItem)))
688
 
        {
689
 
          if (keyItem->isNode())
690
 
          {
691
 
            domainNode.transfer(keyItem);
692
 
            break;
693
 
          }
694
 
 
695
 
          node = domainNode;
696
 
          index->insert(keyItem, node);
697
 
        }
698
 
      }
699
 
    }
700
 
  }
701
 
  catch(...)
702
 
  {
703
 
    sourceIter->close();
704
 
 
705
 
    throw;
706
 
  }
707
 
 
708
 
  sourceIter->close();
709
 
}
710
 
 
711
 
 
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)
721
 
{
722
 
  store::Index_t index;
723
 
  store::Item* non_const_items = const_cast<store::Item*>(qname.getp());
724
 
 
725
 
  if (!theIndices.get(non_const_items, index))
726
 
  {
727
 
    throw ZORBA_EXCEPTION(
728
 
      zerr::ZSTR0002_INDEX_DOES_NOT_EXIST,
729
 
      ERROR_PARAMS( qname->getStringValue() )
730
 
    );
731
 
  }
732
 
 
733
 
  deleteIndex(qname);
734
 
 
735
 
  try
736
 
  {
737
 
    createIndex(qname, index->getSpecification(), sourceIter);
738
 
  }
739
 
  catch (...)
740
 
  {
741
 
    addIndex(index);
742
 
    throw;
743
 
  }
744
 
 
745
 
  return index;
746
 
}
747
 
 
748
 
/*******************************************************************************
749
 
 
750
 
********************************************************************************/
751
 
void SimpleStore::addIndex(store::Index_t& index)
752
 
{
753
 
  if (index == NULL)
754
 
    return;
755
 
 
756
 
  store::Item* qname = const_cast<store::Item*>(index->getName());
757
 
 
758
 
  theIndices.insert(qname, index);
759
 
}
760
 
 
761
 
 
762
 
/*******************************************************************************
763
 
 
764
 
********************************************************************************/
765
 
store::Index* SimpleStore::getIndex(const store::Item* qname)
766
 
{
767
 
  if (qname == NULL)
768
 
    return NULL;
769
 
 
770
 
  store::Item* qname2 = const_cast<store::Item*>(qname);
771
 
  store::Index_t index;
772
 
 
773
 
  if (theIndices.get(qname2, index))
774
 
    return index.getp();
775
 
 
776
 
  return NULL;
777
 
}
778
 
 
779
 
 
780
 
/*******************************************************************************
781
 
 
782
 
********************************************************************************/
783
 
void SimpleStore::deleteIndex(const store::Item* qname)
784
 
{
785
 
  if (qname == NULL)
786
 
    return;
787
 
 
788
 
  store::Item* qname2 = const_cast<store::Item*>(qname);
789
 
 
790
 
  theIndices.erase(qname2);
791
 
}
792
 
 
793
 
 
794
 
/*******************************************************************************
795
 
 
796
 
********************************************************************************/
797
 
store::Iterator_t SimpleStore::listIndexNames()
798
 
{
799
 
  return new NameIterator<IndexSet>(theIndices);
800
 
}
801
 
 
802
 
 
803
 
/*******************************************************************************
804
 
 
805
 
********************************************************************************/
806
 
store::IC_t SimpleStore::activateIC(
807
 
    const store::Item_t& icQName,
808
 
    const store::Item_t& collectionQName,
809
 
    bool& isApplied)
810
 
{
811
 
  ZORBA_ASSERT(icQName != NULL);
812
 
 
813
 
  store::Item* qname = icQName.getp();
814
 
 
815
 
  store::IC_t ic;
816
 
 
817
 
  if (theICs.get(qname, ic))
818
 
  {
819
 
    return ic; // already activated => noop
820
 
  }
821
 
 
822
 
  ic = new ICCollectionImpl(icQName, collectionQName);
823
 
 
824
 
  theICs.insert(qname, ic);
825
 
 
826
 
  isApplied=true;
827
 
  return ic;
828
 
}
829
 
 
830
 
 
831
 
/*******************************************************************************
832
 
 
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,
838
 
    bool& isApplied)
839
 
{
840
 
  ZORBA_ASSERT(icQName != NULL);
841
 
 
842
 
  store::Item* qname = const_cast<store::Item*>(icQName.getp());
843
 
 
844
 
  store::IC_t ic;
845
 
 
846
 
  if (theICs.get(qname, ic))
847
 
  {
848
 
    return ic; // already activated => noop
849
 
  }
850
 
 
851
 
  ic = new ICForeignKeyImpl(qname, fromCollectionQName, toCollectionQName);
852
 
 
853
 
  theICs.insert(qname, ic);
854
 
 
855
 
  isApplied=true;
856
 
  return ic;
857
 
}
858
 
 
859
 
 
860
 
store::IC_t
861
 
SimpleStore::deactivateIC(const store::Item_t& icQName,
862
 
    bool& isApplied)
863
 
{
864
 
  ZORBA_ASSERT(icQName != NULL);
865
 
 
866
 
  store::IC_t ic;
867
 
 
868
 
  if (!theICs.get(icQName.getp(), ic))
869
 
  {
870
 
    return ic; // already deactivated in the same PUL => noop
871
 
  }
872
 
 
873
 
  theICs.erase(icQName.getp());
874
 
  isApplied=true;
875
 
  return ic;
876
 
}
877
 
 
878
 
 
879
 
store::Iterator_t SimpleStore::listActiveICNames()
880
 
{
881
 
  return new NameIterator<ICSet>(theICs);
882
 
}
883
 
 
884
 
 
885
 
store::IC* SimpleStore::getIC(const store::Item* icQName)
886
 
{
887
 
  store::Item* qname = const_cast<store::Item*>(icQName);
888
 
  store::IC_t ic;
889
 
  theICs.get(qname, ic);
890
 
 
891
 
  return ic.getp();
892
 
}
893
 
 
894
 
 
895
 
/*******************************************************************************
896
 
 
897
 
********************************************************************************/
898
 
store::Index*
899
 
SimpleStore::getMap(const store::Item* aQName) const
900
 
{
901
 
  store::Item* lQName = const_cast<store::Item*>(aQName);
902
 
  store::Index_t lIndex;
903
 
  const_cast<IndexSet*>(&theHashMaps)->get(lQName, lIndex);
904
 
 
905
 
  return lIndex.getp();
906
 
}
907
 
 
908
 
 
909
 
/*******************************************************************************
910
 
 
911
 
********************************************************************************/
912
 
store::Iterator_t SimpleStore::listMapNames()
913
 
{
914
 
  return new NameIterator<IndexSet>(theHashMaps);
915
 
}
916
 
 
917
 
 
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
921
226
  an error.
951
256
 
952
257
 
953
258
/*******************************************************************************
954
 
 
955
 
********************************************************************************/
956
 
void SimpleStore::addCollection(store::Collection_t& collection)
957
 
{
958
 
  const store::Item* lName = collection->getName();
959
 
 
960
 
  bool inserted = theCollections->insert(lName, collection);
961
 
 
962
 
  if (!inserted)
963
 
  {
964
 
    throw ZORBA_EXCEPTION(zerr::ZSTR0008_COLLECTION_ALREADY_EXISTS,
965
 
    ERROR_PARAMS(lName->getStringValue()));
966
 
  }
967
 
}
968
 
 
969
 
 
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)
977
 
{
978
 
  if (aName == NULL)
979
 
    return NULL;
980
 
 
981
 
  store::Collection_t collection;
982
 
  if (theCollections->get(aName, collection, aDynamicCollection)) 
983
 
  {
984
 
    return collection;
985
 
  }
986
 
  else
987
 
  {
988
 
    return NULL;
989
 
  }
990
 
}
991
 
 
992
 
 
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)
1000
 
{
1001
 
  if (aName == NULL)
1002
 
    return;
1003
 
 
1004
 
  if (!theCollections->remove(aName, aDynamicCollection))
1005
 
  {
1006
 
    throw ZORBA_EXCEPTION(zerr::ZSTR0009_COLLECTION_NOT_FOUND,
1007
 
    ERROR_PARAMS(aName->getStringValue()));
1008
 
  }
1009
 
}
1010
 
 
1011
 
 
1012
 
/*******************************************************************************
1013
 
  Returns an iterator that lists the QName's of all the available collections.
1014
 
********************************************************************************/
1015
 
store::Iterator_t SimpleStore::listCollectionNames(bool aDynamicCollections)
1016
 
{
1017
 
  return theCollections->names(aDynamicCollections);
1018
 
}
1019
 
 
1020
 
 
1021
 
/*******************************************************************************
1022
 
 
1023
 
********************************************************************************/
1024
 
store::Item_t SimpleStore::loadDocument(
1025
 
    const zstring& baseUri,
1026
 
    const zstring& docUri,
1027
 
    std::istream& stream,
1028
 
    const store::LoadProperties& loadProperties)
1029
 
{
1030
 
  zstring_b urib;
1031
 
 
1032
 
  if (!docUri.empty())
1033
 
    urib.wrap_memory(docUri.data(), docUri.size());
1034
 
 
1035
 
  XmlNode_t root;
1036
 
  bool found = theDocuments.get(urib, root);
1037
 
 
1038
 
  if (found)
1039
 
  {
1040
 
    return root.getp();
1041
 
  }
1042
 
 
1043
 
  XQueryDiagnostics lXQueryDiagnostics;
1044
 
  std::auto_ptr<XmlLoader> loader(getXmlLoader(&lXQueryDiagnostics, loadProperties));
1045
 
 
1046
 
  root = loader->loadXml(baseUri, docUri, stream);
1047
 
 
1048
 
  if (!lXQueryDiagnostics.errors().empty())
1049
 
  {
1050
 
    lXQueryDiagnostics.errors().front()->polymorphic_throw();
1051
 
  }
1052
 
 
1053
 
  if (root != NULL && loadProperties.getStoreDocument())
1054
 
    theDocuments.insert(urib, root);
1055
 
 
1056
 
  return root.getp();
1057
 
}
1058
 
 
1059
 
 
1060
 
/*******************************************************************************
1061
 
  For lazy loading...
1062
 
  Param stream is a heap pointer to an input stream. This is to be deallocated
1063
 
  by Zorba.
1064
 
********************************************************************************/
1065
 
store::Item_t SimpleStore::loadDocument(
1066
 
    const zstring& baseUri,
1067
 
    const zstring& docUri,
1068
 
    std::istream* stream,
1069
 
    const store::LoadProperties& loadProperties)
1070
 
{
1071
 
  store::Item_t docitem;
1072
 
  try
1073
 
  {
1074
 
    //do full loading for now
1075
 
    docitem = loadDocument(baseUri, docUri, *stream, loadProperties);
1076
 
    delete stream;
1077
 
  }
1078
 
  catch(...)
1079
 
  {
1080
 
    delete stream;
1081
 
  }
1082
 
  return docitem;
1083
 
}
1084
 
 
1085
 
 
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)
1093
 
{
1094
 
  ZORBA_ASSERT(!uri.empty());
1095
 
 
1096
 
  if (node == NULL || !node->isNode())
1097
 
  {
1098
 
    RAISE_ERROR_NO_LOC(zerr::ZAPI0021_ITEM_TO_LOAD_IS_NOT_NODE, ERROR_PARAMS(uri));
1099
 
  }
1100
 
 
1101
 
  XmlNode_t root = reinterpret_cast<XmlNode*>(node.getp());
1102
 
 
1103
 
  bool inserted = theDocuments.insert(uri, root);
1104
 
 
1105
 
  if (!inserted && node.getp() != root.getp())
1106
 
  {
1107
 
    RAISE_ERROR_NO_LOC(zerr::ZAPI0020_DOCUMENT_ALREADY_EXISTS, ERROR_PARAMS(uri));
1108
 
  }
1109
 
 
1110
 
  ZORBA_FATAL(node.getp() == root.getp(), "");
1111
 
}
1112
 
 
1113
 
 
1114
 
/*******************************************************************************
1115
 
  Return an rchandle to an iterator over the set of documents in the store
1116
 
********************************************************************************/
1117
 
store::Iterator_t SimpleStore::getDocumentNames() const
1118
 
{
1119
 
  return new DocumentNameIterator<DocumentSet>(theDocuments);
1120
 
}
1121
 
 
1122
 
 
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)
1128
 
{
1129
 
  if (uri.empty())
1130
 
    return NULL;
1131
 
 
1132
 
  XmlNode_t root;
1133
 
 
1134
 
  bool found = theDocuments.get(uri, root);
1135
 
 
1136
 
  if (found)
1137
 
    return root.getp();
1138
 
 
1139
 
  return NULL;
1140
 
}
1141
 
 
1142
 
 
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)
1148
 
{
1149
 
  if (uri.empty())
1150
 
    return;
1151
 
 
1152
 
  theDocuments.erase(uri);
1153
 
}
1154
 
 
1155
 
 
1156
 
/*******************************************************************************
1157
 
  Delete all the documents.
1158
 
********************************************************************************/
1159
 
void SimpleStore::deleteAllDocuments()
1160
 
{
1161
 
  theDocuments.clear();
1162
 
}
1163
 
 
1164
 
 
1165
 
/*******************************************************************************
1166
 
 
1167
 
********************************************************************************/
1168
 
store::Index_t
1169
 
SimpleStore::createHashMap(
1170
 
    const store::Item_t& aQName,
1171
 
    const store::IndexSpecification& aSpec)
1172
 
{
1173
 
  store::Index_t lIndex;
1174
 
 
1175
 
  if (theHashMaps.get(aQName.getp(), lIndex))
1176
 
  {
1177
 
    throw ZORBA_EXCEPTION(
1178
 
      zerr::ZSTR0001_INDEX_ALREADY_EXISTS,
1179
 
      ERROR_PARAMS( aQName->getStringValue() )
1180
 
    );
1181
 
  }
1182
 
 
1183
 
  lIndex = new ValueHashIndex(aQName, aSpec);
1184
 
 
1185
 
  addHashMap(lIndex);
1186
 
 
1187
 
  return lIndex;
1188
 
}
1189
 
 
1190
 
 
1191
 
/*******************************************************************************
1192
 
 
1193
 
********************************************************************************/
1194
 
store::Index_t
1195
 
SimpleStore::destroyHashMap(const store::Item_t& aQName)
1196
 
{
1197
 
  store::Index_t lIndex;
1198
 
  if (!theHashMaps.get(aQName.getp(), lIndex))
1199
 
  {
1200
 
    throw ZORBA_EXCEPTION(
1201
 
      zerr::ZDDY0023_INDEX_DOES_NOT_EXIST,
1202
 
      ERROR_PARAMS( aQName->getStringValue() )
1203
 
    );
1204
 
  }
1205
 
  theHashMaps.erase(aQName.getp());
1206
 
  return lIndex;
1207
 
}
1208
 
 
1209
 
 
1210
 
/*******************************************************************************
1211
 
 
1212
 
********************************************************************************/
1213
 
store::Index_t
1214
 
SimpleStore::getHashMap(const store::Item_t& aQName) const
1215
 
{
1216
 
  store::Index_t lIndex;
1217
 
  if (const_cast<IndexSet*>(&theHashMaps)->get(aQName.getp(), lIndex))
1218
 
  {
1219
 
    return lIndex;
1220
 
  }
1221
 
  else
1222
 
  {
1223
 
    return 0;
1224
 
  }
1225
 
}
1226
 
 
1227
 
 
1228
 
/*******************************************************************************
1229
 
 
1230
 
********************************************************************************/
1231
 
void
1232
 
SimpleStore::addHashMap(const store::Index_t& aIndex)
1233
 
{
1234
 
  store::Item* lName = aIndex->getName();
1235
 
  store::Index_t lIndex = aIndex;
1236
 
  theHashMaps.insert(lName, lIndex);
1237
 
}
1238
 
 
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
1244
 
{
1245
 
  ZORBA_FATAL(node1->isNode(), "");
1246
 
  ZORBA_FATAL(node2->isNode(), "");
1247
 
 
1248
 
  if (node1 == node2)
1249
 
    return 0;
1250
 
 
1251
 
  XmlNode* n1 = static_cast<XmlNode*>(node1);
1252
 
  XmlNode* n2 = static_cast<XmlNode*>(node2);
1253
 
 
1254
 
  return (short)n1->compare2(n2);
1255
 
}
1256
 
 
1257
 
 
1258
 
/*******************************************************************************
1259
 
  Sorts the items of the passed iterator
1260
 
 
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,
1268
 
    bool ascendent,
1269
 
    bool duplicateElemination,
1270
 
    bool aAllowAtomics)
1271
 
{
1272
 
  if (aAllowAtomics)
1273
 
    return new StoreNodeSortOrAtomicIterator(input, ascendent, duplicateElemination);
1274
 
  else
1275
 
    return new StoreNodeSortIterator(input, ascendent, duplicateElemination);
1276
 
}
1277
 
 
1278
 
 
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,
1285
 
    bool aAllowAtomics)
1286
 
{
1287
 
  if (aAllowAtomics)
1288
 
    return new StoreNodeDistinctOrAtomicIterator(input);
1289
 
  else
1290
 
    return new StoreNodeDistinctIterator(input, false);
1291
 
}
1292
 
 
1293
 
 
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)
1301
 
{
1302
 
  return new StoreNodeDistinctIterator(input, true);
1303
 
}
1304
 
 
1305
 
 
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)
1312
 
{
1313
 
#ifdef TEXT_ORDPATH
1314
 
  const OrdPathNode* n = static_cast<const OrdPathNode*>(node);
1315
 
 
1316
 
  return theItemFactory->createStructuralAnyURI(result,
1317
 
                                                n->getCollectionId(),
1318
 
                                                n->getTreeId(),
1319
 
                                                n->getNodeKind(),
1320
 
                                                n->getOrdPath());
1321
 
#else
1322
 
  if (node->getNodeKind() == store::StoreConsts::textNode)
1323
 
  {
1324
 
    OrdPath ordPath;
1325
 
    const TextNode* n = static_cast<const TextNode*>(node);
1326
 
    n->getOrdPath(ordPath);
1327
 
 
1328
 
    return theItemFactory->createStructuralAnyURI(result,
1329
 
                                                  n->getCollectionId(),
1330
 
                                                  n->getTreeId(),
1331
 
                                                  store::StoreConsts::textNode,
1332
 
                                                  ordPath);
1333
 
  }
1334
 
  else
1335
 
  {
1336
 
    const OrdPathNode* n = static_cast<const OrdPathNode*>(node);
1337
 
 
1338
 
    return theItemFactory->createStructuralAnyURI(result,
1339
 
                                                  n->getCollectionId(),
1340
 
                                                  n->getTreeId(),
1341
 
                                                  n->getNodeKind(),
1342
 
                                                  n->getOrdPath());
1343
 
  }
1344
 
#endif
1345
 
}
1346
 
 
1347
 
 
1348
 
/*******************************************************************************
1349
259
 Computes the reference of the given node.
1350
 
 
 
260
 
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)
1355
265
{
1356
 
  XmlNode* xmlNode = static_cast<XmlNode*>(node);
 
266
  const XmlNode* xmlNode = static_cast<const XmlNode*>(node);
1357
267
 
1358
268
  if (xmlNode->haveReference())
1359
269
  {
1369
279
  uuid_create(&uuid);
1370
280
  zstring uuidStr = uuidToURI(uuid);
1371
281
 
1372
 
  xmlNode->setHaveReference();
 
282
  const_cast<XmlNode*>(xmlNode)->setHaveReference();
1373
283
 
1374
284
  theNodeToReferencesMap.insert(xmlNode, uuidStr);
1375
285
  theReferencesToNodeMap[uuidStr] = node;
1379
289
 
1380
290
 
1381
291
/*******************************************************************************
 
292
  Returns whether a reference has already been generated for the given node.
 
293
 
 
294
  @param item XDM node
 
295
  @return whether a reference has already been generated for the given node.
 
296
********************************************************************************/
 
297
bool SimpleStore::hasReference(const store::Item* node)
 
298
{
 
299
  return static_cast<const XmlNode*>(node)->haveReference();
 
300
}
 
301
 
 
302
 
 
303
/*******************************************************************************
1382
304
  Returns the node which is identified by the given reference.
1383
 
 
 
305
 
1384
306
  @param reference an xs:anyURI item
1385
307
  @result the node identified by the reference, or NULL if no node with the given
1386
308
          reference exists
1408
330
 
1409
331
 
1410
332
/*******************************************************************************
1411
 
  Returns whether a reference has already been generated for the given node.
1412
 
 
1413
 
  @param item XDM node
1414
 
  @return whether a reference has already been generated for the given node.
1415
 
********************************************************************************/
1416
 
bool SimpleStore::hasReference(const store::Item* node)
1417
 
{
1418
 
  return static_cast<const XmlNode*>(node)->haveReference();
1419
 
}
1420
 
 
1421
 
 
1422
 
/*******************************************************************************
1423
333
  Removes a node from the reference-to-nodes and nodes-to-references maps.
1424
 
 
 
334
 
1425
335
  @param node XDM node
1426
336
  @return whether the node was registered or not.
1427
337
********************************************************************************/
1449
359
}
1450
360
 
1451
361
 
1452
 
/*******************************************************************************
1453
 
 
1454
 
********************************************************************************/
1455
 
bool SimpleStore::getPathInfo(
1456
 
    const store::Item*               docUriItem,
1457
 
    std::vector<const store::Item*>& contextPath,
1458
 
    std::vector<const store::Item*>& relativePath,
1459
 
    bool                             isAttrPath,
1460
 
    bool&                            found,
1461
 
    bool&                            unique)
1462
 
{
1463
 
  zstring docUri;
1464
 
  docUriItem->getStringValue2(docUri);
1465
 
 
1466
 
  XmlNode_t docRoot = BASE_NODE(getDocument(docUri));
1467
 
 
1468
 
  if (docRoot == NULL)
1469
 
    return false;
1470
 
 
1471
 
#ifdef DATAGUIDE
1472
 
  GuideNode* guideRoot = docRoot->getDataGuide();
1473
 
 
1474
 
  if (!guideRoot)
1475
 
    return false;
1476
 
 
1477
 
  guideRoot->getPathInfo(contextPath, relativePath, isAttrPath, found, unique);
1478
 
#endif
1479
 
  return true;
1480
 
}
1481
 
 
1482
 
 
1483
 
/*******************************************************************************
1484
 
  Creates a new TempSeq. The instance can be used, e.g. for variable bindings
1485
 
 
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
1489
 
                    this to false.
1490
 
********************************************************************************/
1491
 
TempSeq_t SimpleStore::createTempSeq(const store::Iterator_t& iterator, bool lazy)
1492
 
{
1493
 
  if(lazy)
1494
 
  {
1495
 
    //tempSeq = new SimpleTempSeq(iterator, copyNodes);
1496
 
    return new SimpleLazyTempSeq(iterator);
1497
 
  }
1498
 
  else
1499
 
  {
1500
 
    return new SimpleTempSeq(iterator);
1501
 
  }
1502
 
}
1503
 
 
1504
 
 
1505
 
/*******************************************************************************
1506
 
  Creates an empty TempSeq.
1507
 
********************************************************************************/
1508
 
TempSeq_t SimpleStore::createTempSeq(bool lazy)
1509
 
{
1510
 
  if (lazy)
1511
 
  {
1512
 
    return new SimpleLazyTempSeq();
1513
 
  }
1514
 
  else
1515
 
  {
1516
 
    return new SimpleTempSeq();
1517
 
  }
1518
 
}
1519
 
 
1520
 
 
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)
1526
 
{
1527
 
  return new SimpleTempSeq(items);
1528
 
}
1529
 
 
1530
 
 
1531
 
/*******************************************************************************
1532
 
  Creates a temp seq initialized by the given item.
1533
 
********************************************************************************/
1534
 
TempSeq_t SimpleStore::createTempSeq(store::Item_t& item)
1535
 
{
1536
 
  return new SimpleTempSeq(item);
1537
 
}
1538
 
 
1539
 
 
1540
 
#ifndef ZORBA_NO_FULL_TEXT
1541
 
void SimpleStore::setStemmerProvider( internal::StemmerProvider const *p ) 
1542
 
{
1543
 
  theStemmerProvider = p;
1544
 
}
1545
 
 
1546
 
 
1547
 
void SimpleStore::setTokenizerProvider( TokenizerProvider const *p ) 
1548
 
{
1549
 
  theTokenizerProvider = p;
1550
 
}
1551
 
 
1552
 
 
1553
 
internal::StemmerProvider const* SimpleStore::getStemmerProvider() const 
1554
 
{
1555
 
  return theStemmerProvider ?
1556
 
    theStemmerProvider : &internal::StemmerProvider::get_default();
1557
 
}
1558
 
 
1559
 
 
1560
 
TokenizerProvider const* SimpleStore::getTokenizerProvider() const 
1561
 
{
1562
 
  return theTokenizerProvider ?
1563
 
    theTokenizerProvider : &default_tokenizer_provider();
1564
 
}
1565
 
#endif /* ZORBA_NO_FULL_TEXT */
1566
 
 
1567
 
} // namespace store
 
362
} // namespace simplestore
1568
363
} // namespace zorba
1569
 
/* vim:set et sw=2 ts=2: */