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 #pragma once 17 #ifndef ZORBA_API_XQUERY_IMPL 18 #define ZORBA_API_XQUERY_IMPL 19 20 #include <iostream> 21 #include <zorba/xquery.h> 22 #include <zorba/sax2.h> 23 24 #include <zorba/api_shared_types.h> 25 26 #include "zorbautils/mutex.h" 27 28 #include "common/shared_types.h" 29 30 #include "zorbaserialization/class_serializer.h" 31 32 33 namespace zorba 34 { 35 36 class RCObject; 37 #ifdef ZORBA_WITH_DEBUGGER 38 class ZorbaDebugger; 39 class DebuggerRuntime; 40 class DebuggerCommons; 41 #endif 42 class DynamicContextImpl; 43 class StaticContextImpl; 44 class ResultIteratorImpl; 45 class dynamic_context; 46 class CompilerCB; 47 class StaticCollectionManagerSetImpl; 48 49 50 /******************************************************************************* 51 52 - theFileName : 53 The filename of the file containing the query. It is taken into account when 54 computing the base uri property of the static context. It may be an empty 55 string, if query does not come from a file. 56 57 - theStaticContext : 58 rchandle to the root sctx obj for this xquery. This sctx may be (a) a child 59 of the zorba root sctx, or (b) a child of an sctx that was created by the 60 application, or (c) if this XQuery obj is a clone of another XQuery obj, a 61 child of the root sctx of the other XQuery obj, or (d) if this XQuery obj 62 is one that is created internally by StaticContextImpl::loadProlog(), the 63 sctx that was created by the application. In cases (a), (b), and (c), the 64 root sctx of the query is created by the xquery obj itself. 65 66 - theStaticContextWrapper : 67 Pointer to a StaticContextImpl obj that wraps theStaticContext and which is 68 created when the application asks for the static context of the query (see 69 getStaticContext() method). The pointer is cached, so that it is returned 70 if the application askes for the static context again. 71 72 - theCompilerCB : 73 A CompilerCB obj provides some additional context that is needed during the 74 compilation and execution of a query. See src/compiler/api/compilercb.h for 75 deetails. Each xquery obj has its own associated CompilerCB obj, which is 76 created by the constructor of the xquery obj. 77 78 - thePlanProxy : 79 An rchandle to a PlanProxy obj that provides thread-safe access to the root 80 iterator of the plan iterator tree. A PlanProxy obj is needed for thread 81 safety, because the plan is shared among cloned queries, but the PlanIterator 82 class does not do thread-safe ref counting. All clones share the same 83 PlanProxy obj, which is a sunchronized RCObject. This way, no ref count 84 ops are performed on the plan root, except when the plan proxy itself is 85 destroyed, which can be done by a single therad only. 86 87 - theDynamicContext : 88 The dynamic context for this query. Always belongs to the query. It is created 89 by the XQueryImpl constructor. 90 91 - theDynamicContextWrapper : 92 93 - theResultIterator : 94 There is an 0:1 relationship between ResultIterator and XQuery objs. This 95 relationship is implemented by (a) theResultIterator, which is a ptr to 96 a ResultIterator that has been created by the XQuery::iterator() method, 97 and (b) a ptr in this ResultIterator pointing back to the associated 98 XQuery. This way we can guarantee that no ResultIterator exists when its 99 associated XQuery is closed (see ~ResultIterator() and XQuery::close()). 100 101 - theIsClosed : 102 Set to true when the query has been closed. Used to check that after closing 103 a query, no operations can be performed on that query anymore. 104 105 - theExecuting : 106 Set to true while the query is being executed. It is used to make sure that 107 a second execution of the same XQuery obj cannot be started while a previous 108 execution is still going on. 109 110 - theXQueryDiagnostics : 111 Each query has its own XQueryDiagnostics. The XQueryDiagnostics accumulates 112 query errors/warnings that need to be processed in some deferred fashion. 113 114 - theDiagnosticHandler : 115 Normally, this is an object provided by the application to handle errors in 116 some specific way (see include/zorba/diagnostic_handler.h and src/api/zorbaimpl.cpp). 117 If the application does not provide an error handler, a default zorba error 118 handler is created for the query (the default error handler just throws a 119 ZorbaException). 120 121 - theUserDiagnosticHandler : 122 True if the error handler was provided by the application (in which case it 123 is not owned by the query). Also true if this is a cloned query, in which 124 case, theDiagnosticHandler points to the same error handler obj as the orignal 125 query. False otherwise (in which case the error handler is owned by the 126 query). 127 128 - theSAX2Handler : 129 sax content handler that provide event-based xml parser 130 131 - theIsDebugMode : 132 133 - theProfileName : 134 135 - theStaticCollectionMgr : 136 StaticCollectionManager object for all statically declared collections in this 137 query or any transitively imported module. It's created lazily upon request 138 and destroyed when this XQueryImpl object is destroyed. 139 140 ********************************************************************************/ 141 class XQueryImpl : public XQuery , public ::zorba::serialization::SerializeBaseClass 142 { 143 friend class ResultIteratorImpl; 144 friend class StaticContextImpl; // StaticContextImpl::loadProlog() needs this 145 friend class DynamicContextImpl; 146 friend class CompilerCB; 147 #ifdef ZORBA_WITH_DEBUGGER 148 friend class ZorbaDebugger; 149 friend class DebuggerRuntime; 150 #endif 151 152 protected: 153 154 class PlanProxy : public RCObject 155 { 156 public: 157 SYNC_CODE(mutable RCLock theRCLock;) 158 159 rchandle<SimpleRCObject> theRootIter; 160 161 public: 162 SERIALIZABLE_CLASS(PlanProxy) 163 SERIALIZABLE_CLASS_CONSTRUCTOR2(PlanProxy, RCObject) 164 void serialize(::zorba::serialization::Archiver& ar); 165 166 public: getSharedRefCounter()167 long* getSharedRefCounter() const { return NULL; } 168 169 SYNC_CODE(virtual RCLock* getRCLock() const { return &theRCLock; }) 170 171 PlanProxy(PlanIter_t& root); 172 }; 173 174 typedef rchandle<PlanProxy> PlanProxy_t; 175 176 protected: 177 178 SYNC_CODE(mutable Mutex theMutex;) 179 180 // static stuff 181 zstring theFileName; 182 183 static_context_t theStaticContext; 184 185 mutable StaticContextImpl * theStaticContextWrapper; 186 187 CompilerCB * theCompilerCB; 188 189 PlanProxy_t thePlanProxy; 190 191 // dynamic stuff 192 dynamic_context * theDynamicContext; 193 194 mutable DynamicContextImpl * theDynamicContextWrapper; 195 196 ResultIteratorImpl * theResultIterator; 197 198 bool theExecuting; 199 200 bool theIsClosed; 201 202 // utility stuff 203 XQueryDiagnostics * theXQueryDiagnostics; 204 DiagnosticHandler * theDiagnosticHandler; 205 bool theUserDiagnosticHandler; 206 207 SAX2_ContentHandler * theSAX2Handler; 208 209 double theDocLoadingUserTime; 210 double theDocLoadingTime; 211 212 private: 213 #ifdef ZORBA_WITH_DEBUGGER 214 bool theIsDebugMode; 215 #endif 216 std::string theProfileName; 217 218 mutable StaticCollectionManagerSetImpl* theCollMgr; 219 220 public: 221 SERIALIZABLE_CLASS(XQueryImpl) 222 XQueryImpl(::zorba::serialization::Archiver& ar); 223 void serialize(::zorba::serialization::Archiver& ar); 224 225 public: 226 XQueryImpl(); 227 228 ~XQueryImpl(); 229 230 void setFileName(const String&); 231 232 String getFileName(); 233 234 void setTimeout(long aTimeout /* = -1 */); 235 236 double getDocLoadingUserTime() const; 237 238 double getDocLoadingTime() const; 239 240 #ifdef ZORBA_WITH_DEBUGGER 241 void setDebugMode(bool aDebugMode); 242 243 bool isDebugMode() const; 244 #endif 245 246 void setProfileName(std::string aProfileName); 247 248 std::string getProfileName() const; 249 250 void registerDiagnosticHandler(DiagnosticHandler*); 251 252 DiagnosticHandler* getRegisteredDiagnosticHandler(); 253 254 DiagnosticHandler* getRegisteredDiagnosticHandlerNoSync(); 255 256 void resetDiagnosticHandler(); 257 258 void compile(const String&); 259 260 void compile( 261 const String&, 262 const Zorba_CompilerHints_t& aHints); 263 264 void compile( 265 const String&, 266 const StaticContext_t&, 267 const Zorba_CompilerHints_t& aHints); 268 269 void compile( 270 std::istream&, 271 const Zorba_CompilerHints_t& aHints); 272 273 void compile( 274 std::istream&, 275 const StaticContext_t&, 276 const Zorba_CompilerHints_t& aHints); 277 278 void loadProlog( 279 const String&, 280 const StaticContext_t&, 281 const Zorba_CompilerHints_t& aHints); 282 283 void parse(std::istream&); 284 285 const StaticContext* getStaticContext() const; 286 287 void getExternalVariables(Iterator_t& aVarsIter) const; 288 289 bool isUpdating() const; 290 291 bool isSequential() const; 292 293 bool saveExecutionPlan( 294 std::ostream& os, 295 Zorba_binary_plan_format_t archive_format = ZORBA_USE_BINARY_ARCHIVE, 296 Zorba_save_plan_options_t save_options = DONT_SAVE_UNUSED_FUNCTIONS); 297 298 bool loadExecutionPlan(std::istream& is, SerializationCallback* aCallback = 0); 299 300 void printPlan(std::ostream& aStream, bool aDotFormat = false) const; 301 302 DynamicContext* getDynamicContext() const; 303 304 void execute(std::ostream&, const Zorba_SerializerOptions_t* = NULL); 305 306 void execute( 307 std::ostream& aOutStream, 308 itemHandler aCallbackFunction, 309 void* aCallbackData, 310 const Zorba_SerializerOptions_t* aSerOptions = NULL); 311 312 void execute(); 313 314 Iterator_t iterator(); 315 316 void registerSAXHandler(SAX2_ContentHandler* aSAXHandler); 317 318 void executeSAX(SAX2_ContentHandler* aSAXHandler); 319 320 void executeSAX(); 321 322 #ifdef ZORBA_WITH_DEBUGGER 323 void 324 debug( 325 const std::string& host, 326 unsigned short port); 327 328 virtual void 329 debug( 330 std::ostream& outStream, 331 Zorba_SerializerOptions& serOptions, 332 const std::string& host, 333 unsigned short port); 334 335 void 336 debug( 337 std::ostream& outStream, 338 itemHandler callbackFunction, 339 void* callbackData, 340 Zorba_SerializerOptions& serOptions, 341 const std::string& host, 342 unsigned short port); 343 #endif 344 345 void close(); 346 isClosed()347 bool isClosed() const { return theIsClosed; } 348 349 XQuery_t clone() const; 350 351 StaticCollectionManager* 352 getStaticCollectionManager() const; 353 354 protected: 355 356 void doCompile( 357 std::istream&, 358 const Zorba_CompilerHints_t& aHints, 359 bool fork_sctx, 360 ulong& nextVarId); 361 362 PlanWrapper_t generateWrapper(); 363 364 // special serialize and applyUpdate function that is used by debugger 365 // and by the public serialize and applyUpdate functions, respectively. 366 // they are passed an opened PlanWrapper 367 // important: this function does not (read/write) lock the store. this 368 // needs to be done by the caller of this function 369 // also note that the PlanWrapper that is passed to this function needs 370 // to be generated by the generateWrapper of the same object 371 // there is currently no check that enforces this 372 // after this function has finished, the PlanWrapper also needs to be 373 // closed by the caller 374 void serialize( 375 std::ostream&, 376 PlanWrapper_t& aWrapper, 377 const Zorba_SerializerOptions_t* = NULL); 378 379 void serialize( 380 std::ostream&, 381 PlanWrapper_t& aWrapper, 382 itemHandler aHandler, 383 void* aHandlerData, 384 const Zorba_SerializerOptions_t* = NULL); 385 386 void removeResultIterator(const ResultIteratorImpl* iter); 387 388 void checkNotClosed() const; 389 390 void checkCompiled() const; 391 392 void checkNotCompiled() const; 393 394 void checkNotExecuting() const; 395 396 #ifdef ZORBA_WITH_DEBUGGER 397 void checkIsDebugMode() const; 398 #endif 399 400 void notifyAllWarnings() const; 401 402 bool isBoundVariable(const String& aNamespace, const String& aLocalname) const; 403 }; 404 405 406 std::ostream& operator<< (std::ostream& os, const XQuery_t& aQuery); 407 408 std::ostream& operator<< (std::ostream& os, XQuery* aQuery); 409 410 411 } /* namespace zorba */ 412 #endif 413 414 /* 415 * Local variables: 416 * mode: c++ 417 * End: 418 */ 419 /* vim:set et sw=2 ts=2: */ 420