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_DYNAMIC_CONTEXT_H
18 #define ZORBA_DYNAMIC_CONTEXT_H
19 
20 #include <zorba/external_function_parameter.h>
21 
22 #include "zorbautils/hashmap_zstring.h"
23 #include "zorbautils/hashmap_itemp.h"
24 
25 #include "common/shared_types.h"
26 
27 #include "store/api/shared_types.h"
28 
29 
30 namespace zorba {
31 
32 
33 template <class V> class ItemPointerHashMap;
34 
35 
36 /*******************************************************************************
37   The dynamic context stores the following info:
38 
39   - The current date and time, i.e the date and time when the dynamic context
40     was created.
41   - The current time in mili-secs.
42   - The local timezone (obtained from the machine where zorba is running)
43   - The default collection uri (the one to use when fn:collection is invoked
44     with no argument)
45   - The context item for the whole query, if any.
46   - The position of the context item, if any.
47   - A hasmap mapping the name of each prolog or block-local variable to its
48     current value, which is either a single item or a temp sequence.
49   - A map mapping the uri of each index to the store object representing the
50     index (store::Index_t)
51 ********************************************************************************/
52 class dynamic_context
53 {
54   friend class DebugIterator;
55 
56 public:
57 
58   static enum  ID_VARS { IDVAR_CONTEXT_ITEM=1, IDVAR_CONTEXT_ITEM_POSITION, IDVAR_CONTEXT_ITEM_SIZE, MAX_IDVARS_RESERVED  } IDVARS_RESERVED;
59 
60   struct VarValue
61   {
62     typedef enum
63     {
64       undeclared,
65       declared,
66       item,
67       temp_seq,
68     } ValueState;
69 
70     union
71     {
72       store::Item*     item;
73       store::TempSeq*  temp_seq;
74     }           theValue;
75 
76     ValueState  theState;
77 
VarValueVarValue78     VarValue() : theState(undeclared)
79     {
80       theValue.item = NULL;
81     }
82 
83     VarValue(const VarValue& other);
84 
85     ~VarValue();
86 
isSetVarValue87     bool isSet() const { return (theState == item || theState == temp_seq); }
88 
hasItemValueVarValue89     bool hasItemValue() const { return (theState == item); }
90 
hasSeqValueVarValue91     bool hasSeqValue() const { return (theState == temp_seq); }
92   };
93 
94 protected:
95 
96   struct dctx_value_t
97   {
98     typedef enum
99     {
100       no_val,
101       ext_func_param, // params that can be used by ext. functions
102       ext_func_param_typed
103     } val_type_t;
104 
105     val_type_t  type;
106     void*       func_param;
107   };
108 
109   ZSTRING_HASH_MAP(dctx_value_t, ValueMap);
110 
111   ITEM_PTR_HASH_MAP(store::Index_t, IndexMap);
112 
113   typedef std::map<const zstring,const zstring> EnvVarMap;
114 
115 protected:
116   dynamic_context            * theParent;
117 
118   store::Item_t                theCurrentDateTime;
119   long                         theTimezone;
120 
121   store::Item_t                theDefaultCollectionUri;
122 
123   std::vector<VarValue>        theVarValues;
124 
125   ValueMap                   * keymap;
126 
127   IndexMap                   * theAvailableIndices;
128 
129   IndexMap                   * theAvailableMaps;
130 
131     //MODIFY
132   EnvVarMap                  * theEnvironmentVariables;
133 
134 public:
135   double                       theDocLoadingUserTime;
136   double                       theDocLoadingTime;
137 
138 public:
139   dynamic_context(dynamic_context* parent = NULL);
140 
141   ~dynamic_context();
142 
getParent()143   dynamic_context* getParent() { return theParent; }
144 
145   store::Item_t get_default_collection() const;
146 
147   void set_default_collection(const store::Item_t& default_collection_uri);
148 
149   void set_current_date_time(const store::Item_t&);
150 
151   void reset_current_date_time();
152 
153   store::Item_t get_current_date_time() const;
154 
155   store::Item_t get_current_time_millis() const;
156 
157   void set_environment_variables();
158 
159   store::Item_t get_environment_variable(const zstring& varname);
160 
161   store::Iterator_t available_environment_variables();
162 
163   void set_implicit_timezone(long tzone_seconds);
164 
165   long get_implicit_timezone() const;
166 
get_variables()167   const std::vector<VarValue>& get_variables() const { return theVarValues; }
168 
169   void add_variable(ulong varid, store::Item_t& value);
170 
171   void add_variable(ulong varid, store::Iterator_t& value);
172 
173   void declare_variable(ulong varid);
174 
175   void set_variable(
176       ulong varid,
177       const store::Item_t& varname,
178       const QueryLoc& loc,
179       store::Item_t& value);
180 
181   void set_variable(
182       ulong varid,
183       const store::Item_t& varname,
184       const QueryLoc& loc,
185       store::Iterator_t& value);
186 
187   void unset_variable(
188       ulong varid,
189       const store::Item_t& varname,
190       const QueryLoc& loc);
191 
192 
193   void get_variable(
194         ulong varid,
195         const store::Item_t& varname,
196         const QueryLoc& loc,
197         store::Item_t& itemValue,
198         store::TempSeq_t& seqValue) const;
199 
200   bool is_set_variable(ulong varid) const;
201 
202   bool exists_variable(ulong varid) const;
203 
204   ulong get_next_var_id() const;
205 
206   store::Index* getIndex(store::Item* qname) const;
207 
208   void bindIndex(store::Item* qname, store::Index_t& index);
209 
210   void unbindIndex(store::Item* qname);
211 
212   store::Index* getMap(store::Item* qname) const;
213 
214   void bindMap(store::Item* qname, store::Index_t& index);
215 
216   void unbindMap(store::Item* qname);
217 
218   void getMapNames(std::vector<store::Item_t>& names) const;
219 
220   /**
221    * Lists all active integrity constraints.
222    */
223   store::Iterator_t listActiveICNames();
224 
225   /**
226    * Returns IC object representing the integriti constraint.
227    * NULL if IC is not active.
228    */
229   store::IC* getIC(const store::Item* qname);
230 
231   bool addExternalFunctionParam(const std::string& aName, void* aValue);
232 
233   bool getExternalFunctionParam(const std::string& aName, void*& aValue) const;
234 
235   bool addExternalFunctionParameter(
236      const std::string& aName,
237      ExternalFunctionParameter* aValue);
238 
239   ExternalFunctionParameter* getExternalFunctionParameter(
240       const std::string& aName) const;
241 
242 protected:
lookup_once(const std::string & key,dctx_value_t & val)243   bool lookup_once(const std::string& key, dctx_value_t& val) const
244   {
245     if (keymap)
246     {
247       ValueMap::iterator lIter = keymap->find(key);
248       if (lIter != keymap->end())
249       {
250         val = lIter.getValue();
251         return true;
252       }
253     }
254     return false;
255   }
256 
context_value(const std::string & key,dctx_value_t & val)257   bool context_value(const std::string& key, dctx_value_t& val) const
258   {
259     if (lookup_once(key, val))
260     {
261       return true;
262     }
263     return theParent == NULL ? false : theParent->context_value(key, val);
264   }
265 
context_value(const std::string & key,dctx_value_t & val,ValueMap ** map)266   bool context_value(const std::string& key, dctx_value_t& val, ValueMap **map)
267   {
268     if (lookup_once (key, val))
269     {
270       if (map != NULL) *map = keymap;
271       return true;
272     }
273     return theParent == NULL ? false : theParent->context_value(key, val, map);
274   }
275 
276   void destroy_dctx_value(dctx_value_t *);
277 };
278 
279 
280 } /* namespace zorba */
281 #endif /* ZORBA_DYNAMIC_CONTEXT_H */
282 
283 /*
284  * Local variables:
285  * mode: c++
286  * End:
287  */
288 /* vim:set et sw=2 ts=2: */
289