Merge lp:~zorba-coders/zorba/xqxq-url-resolver into lp:zorba/xqxq-module
- xqxq-url-resolver
- Merge into xqxq-module
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Sorin Marian Nasoi | ||||
Approved revision: | 44 | ||||
Merged at revision: | 40 | ||||
Proposed branch: | lp:~zorba-coders/zorba/xqxq-url-resolver | ||||
Merge into: | lp:zorba/xqxq-module | ||||
Diff against target: |
585 lines (+438/-4) 14 files modified
src/xqxq.xq (+115/-1) src/xqxq.xq.src/xqxq.cpp (+145/-2) src/xqxq.xq.src/xqxq.h (+39/-1) test/ExpQueryResults/xqxq/uri-mapper.xml.res (+2/-0) test/ExpQueryResults/xqxq/uri-mapper2.xml.res (+2/-0) test/ExpQueryResults/xqxq/url-module-resolver.xml.res (+2/-0) test/ExpQueryResults/xqxq/url-schema-resolver.xml.res (+2/-0) test/ExpQueryResults/xqxq/url-schema-resolver2.xml.res (+2/-0) test/Queries/xqxq/test.xsd (+14/-0) test/Queries/xqxq/uri-mapper.xq (+27/-0) test/Queries/xqxq/uri-mapper2.xq (+22/-0) test/Queries/xqxq/url-module-resolver.xq (+17/-0) test/Queries/xqxq/url-schema-resolver.xq (+20/-0) test/Queries/xqxq/url-schema-resolver2.xq (+29/-0) |
||||
To merge this branch: | bzr merge lp:~zorba-coders/zorba/xqxq-url-resolver | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sorin Marian Nasoi | Approve | ||
Matthias Brantner | Approve | ||
Chris Hillery | Approve | ||
Review via email: mp+130460@code.launchpad.net |
This proposal supersedes a proposal from 2012-09-10.
Commit message
Bug 903797: add feature to prepare-
Description of the change
Sorin Marian Nasoi (sorin.marian.nasoi) wrote : Posted in a previous version of this proposal | # |
Chris Hillery (ceejatec) wrote : Posted in a previous version of this proposal | # |
I initially saw some bad memory hits when I did a build of this branch as well, but after merging the latest trunk and doing a clean build, it all looks good. I do not see the memory leaks Sorin noted; I ran the url- tests with valgrind, and the only memory leaks reported were the known ones from inside the http-client module.
Sorin, please re-review now; if you see any problems, try a completely clean re-build. Thanks.
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal | # |
The attempt to merge lp:~zorba-coders/zorba/xqxq-url-resolver into lp:zorba/xqxq-module failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job xqxq-url-
finished. The final status was:
6 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Chris Hillery (ceejatec) wrote : Posted in a previous version of this proposal | # |
Whoops, right - this merge proposal won't pass until https:/
Sorin Marian Nasoi (sorin.marian.nasoi) : Posted in a previous version of this proposal | # |
Matthias Brantner (matthias-brantner) wrote : Posted in a previous version of this proposal | # |
I don't feel comfortable with the QName solution. It would be great if HOFs could be used for this. As far as I understood earlier discussions, this should have been developed together with Nicolae. Using HOFs would also solve the static context problem. Maybe the HOF feature already allows this relatively simple use case.
Can a sequence of mappers be registered?
The documentation should say that mapper:uri-mapper should return xs:string*.
s/lilfetime/
s/recive/receive
s/namesapce/
s/th /the /
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job xqxq-url-
All tests succeeded!
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 1 Approve, 2 Pending.
Matthias Brantner (matthias-brantner) : | # |
Sorin Marian Nasoi (sorin.marian.nasoi) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job xqxq-url-
All tests succeeded!
Preview Diff
1 | === modified file 'src/xqxq.xq' | |||
2 | --- src/xqxq.xq 2012-09-28 13:48:30 +0000 | |||
3 | +++ src/xqxq.xq 2012-10-19 01:25:26 +0000 | |||
4 | @@ -26,9 +26,12 @@ | |||
5 | 26 | module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | 26 | module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; |
6 | 27 | 27 | ||
7 | 28 | declare namespace an = "http://www.zorba-xquery.com/annotations"; | 28 | declare namespace an = "http://www.zorba-xquery.com/annotations"; |
8 | 29 | |||
9 | 30 | declare namespace ver = "http://www.zorba-xquery.com/options/versioning"; | 29 | declare namespace ver = "http://www.zorba-xquery.com/options/versioning"; |
10 | 30 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
11 | 31 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
12 | 32 | |||
13 | 31 | declare option ver:module-version "1.0"; | 33 | declare option ver:module-version "1.0"; |
14 | 34 | declare option op:enable "f:hof"; | ||
15 | 32 | 35 | ||
16 | 33 | (:~ | 36 | (:~ |
17 | 34 | : The function prepares a given XQuery program for execution. | 37 | : The function prepares a given XQuery program for execution. |
18 | @@ -56,6 +59,106 @@ | |||
19 | 56 | xs:anyURI external; | 59 | xs:anyURI external; |
20 | 57 | 60 | ||
21 | 58 | (:~ | 61 | (:~ |
22 | 62 | : The function prepares a given XQuery program for execution. | ||
23 | 63 | : If the program was successfully compiled, the function returns an | ||
24 | 64 | : identifier as xs:anyURI. This URI can be passed to other functions | ||
25 | 65 | : of this module (e.g. to actually evaluate the program). The URI | ||
26 | 66 | : is opaque and its lilfetime is bound by the lifetime of the XQuery | ||
27 | 67 | : program that invoked this function. Further reference or uses | ||
28 | 68 | : of the identifier lead to unexpected results. | ||
29 | 69 | : | ||
30 | 70 | : Important notes regarding the second and third parameters of the function: | ||
31 | 71 | : -------------------------------------------------------------------------- | ||
32 | 72 | : | ||
33 | 73 | : These parameters allow you to specify a URL resolver and a URI mapper | ||
34 | 74 | : for Zorba to use when executing this query. See | ||
35 | 75 | : http://www.zorba-xquery.com/html/documentation/2.7.0/zorba/uriresolvers | ||
36 | 76 | : | ||
37 | 77 | : The second parameter is a function item for a URL | ||
38 | 78 | : resolver. The URL resolver function must recive 2 parameters: | ||
39 | 79 | : A $namespace as xs:string that will contain the url to be resolved. | ||
40 | 80 | : A $entity as xs:string that will contain the type of resolving needed; | ||
41 | 81 | : this can be 2 values "module" and "schema". | ||
42 | 82 | : The function must return an empty sequence when the specified $namespace | ||
43 | 83 | : or $entity are not the ones to be resolved. | ||
44 | 84 | : | ||
45 | 85 | : Example: | ||
46 | 86 | : | ||
47 | 87 | : declare function mymod:url-resolver($namespace as xs:string, $entity as xs:string) | ||
48 | 88 | : { | ||
49 | 89 | : if($namespace = 'http://test.xq') | ||
50 | 90 | : then "module namespace test = 'http://test'; declare function test:foo(){'foo'};" | ||
51 | 91 | : else () | ||
52 | 92 | : }; | ||
53 | 93 | : | ||
54 | 94 | : The URL resolver function's namespace, name, and parameter naming are | ||
55 | 95 | : not restricted by XQXQ. | ||
56 | 96 | : | ||
57 | 97 | : The URL resolver function's return type is not restricted, it could be a string, a sequence, | ||
58 | 98 | : a node, etc. All the outputs types are to be serialized as a string. | ||
59 | 99 | : | ||
60 | 100 | : The third parameter is a function item for a URI mapper. | ||
61 | 101 | : The URI mapper function, just like the URL resolver, receives 2 parameters: | ||
62 | 102 | : A $namespace as xs:string that will contain the URI to be mapped. | ||
63 | 103 | : A $entity as xs:string that will contain the type of resolving needed; | ||
64 | 104 | : this can be 2 values "module" and "schema". | ||
65 | 105 | : The URI mapper must return an empty sequence when the specified $namesapce or $entity | ||
66 | 106 | : are not to be mapped. Unlike the URL resolver this function must return a sequence of strings. | ||
67 | 107 | : | ||
68 | 108 | : Example: | ||
69 | 109 | : | ||
70 | 110 | : declare function mymod:uri-mapper($namespace as xs:string, $entity as xs:string) | ||
71 | 111 | : { | ||
72 | 112 | : if($namespace = 'http://test') | ||
73 | 113 | : then ("http://www.zorba-xquery.com/test", "http://foo.com/schema/test") | ||
74 | 114 | : else () | ||
75 | 115 | : }; | ||
76 | 116 | : | ||
77 | 117 | : The URI mapper function's namespace, name, and parameter naming are | ||
78 | 118 | : not restricted by XQXQ. | ||
79 | 119 | : | ||
80 | 120 | : In order to pass the above URL resolver and URI mapper to this function, | ||
81 | 121 | : use the following syntax: | ||
82 | 122 | : | ||
83 | 123 | : variable $queryID := xqxq:prepare-main-module("..query text..", | ||
84 | 124 | : mymod:url-resolver#2, mymod:uri-mapper#2); | ||
85 | 125 | : | ||
86 | 126 | : That is, the QName of the function followed by "#2". This is XQuery | ||
87 | 127 | : "higher-order function" syntax, meaning the function with the specified | ||
88 | 128 | : QName which takes two arguments. Since URL resolvers and URI mappers | ||
89 | 129 | : must take two arguments, both will always be specified with "#2". | ||
90 | 130 | : | ||
91 | 131 | : Note that parameters 2 and 3 should be declared as follows: | ||
92 | 132 | : as function($url as xs:string, $entity as xs:string) as item() | ||
93 | 133 | : as function($uri as xs:string, $entity as xs:string) as xs:string* | ||
94 | 134 | : However Zorba's implementation of higher-order functions (HOF) is not | ||
95 | 135 | : yet complete enough to allow for this. When Zorba's HOF implementation | ||
96 | 136 | : is complete this function signature will be changed. | ||
97 | 137 | : | ||
98 | 138 | : Both the URL resolver and URI mapper functions are optional, meaning you | ||
99 | 139 | : may pass the empty-sequence () for either. | ||
100 | 140 | : | ||
101 | 141 | : Successfully prepared queries need to be deleted by passing the resulting | ||
102 | 142 | : identifier to the xqxq:delete-query function of this module. | ||
103 | 143 | : | ||
104 | 144 | : @param $main-module-text the XQuery program that should be prepared. | ||
105 | 145 | : The program needs to be a XQuery main module. | ||
106 | 146 | : | ||
107 | 147 | : @param $resolver the URL resolver function. | ||
108 | 148 | : | ||
109 | 149 | : @param $mapper the URI mapper function. | ||
110 | 150 | : | ||
111 | 151 | : @return an identifier for the compiled program that can be passed | ||
112 | 152 | : as arguments to other functions of this module. | ||
113 | 153 | : | ||
114 | 154 | : @error any (static or type) error that may be raised during the compilation | ||
115 | 155 | : of the query. For example, err:XPST0003 if the given XQuery program could | ||
116 | 156 | : not be parsed. | ||
117 | 157 | :) | ||
118 | 158 | declare %an:sequential function xqxq:prepare-main-module($main-module-text as xs:string, $resolver as item()?, $mapper as item()?) as | ||
119 | 159 | xs:anyURI external; | ||
120 | 160 | |||
121 | 161 | (:~ | ||
122 | 59 | : This function compiles a given XQuery library module. It can be used | 162 | : This function compiles a given XQuery library module. It can be used |
123 | 60 | : to compile-check a module. | 163 | : to compile-check a module. |
124 | 61 | : | 164 | : |
125 | @@ -265,3 +368,14 @@ | |||
126 | 265 | :) | 368 | :) |
127 | 266 | declare %an:sequential function xqxq:delete-query($query-key as xs:anyURI) as | 369 | declare %an:sequential function xqxq:delete-query($query-key as xs:anyURI) as |
128 | 267 | empty-sequence() external; | 370 | empty-sequence() external; |
129 | 371 | |||
130 | 372 | |||
131 | 373 | (:~ | ||
132 | 374 | : Internal helper function. Only necessary because of incomplete HOF | ||
133 | 375 | : support in Zorba. | ||
134 | 376 | :) | ||
135 | 377 | declare %private function xqxq:hof-invoker($hof as item(), | ||
136 | 378 | $ns as xs:string, $entity as xs:string) as item()* | ||
137 | 379 | { | ||
138 | 380 | $hof($ns, $entity) | ||
139 | 381 | }; | ||
140 | 268 | 382 | ||
141 | === modified file 'src/xqxq.xq.src/xqxq.cpp' | |||
142 | --- src/xqxq.xq.src/xqxq.cpp 2012-10-01 17:54:38 +0000 | |||
143 | +++ src/xqxq.xq.src/xqxq.cpp 2012-10-19 01:25:26 +0000 | |||
144 | @@ -226,6 +226,116 @@ | |||
145 | 226 | 226 | ||
146 | 227 | /******************************************************************************************* | 227 | /******************************************************************************************* |
147 | 228 | *******************************************************************************************/ | 228 | *******************************************************************************************/ |
148 | 229 | static void streamReleaser(std::istream* aStream) | ||
149 | 230 | { | ||
150 | 231 | delete aStream; | ||
151 | 232 | } | ||
152 | 233 | |||
153 | 234 | void | ||
154 | 235 | PrepareMainModuleFunction::XQXQURIMapper::mapURI( | ||
155 | 236 | String aUri, | ||
156 | 237 | EntityData const* aEntityData, | ||
157 | 238 | std::vector<String>& oUris) | ||
158 | 239 | { | ||
159 | 240 | //Create entityData string to send to the new url resolver | ||
160 | 241 | String lDataKind; | ||
161 | 242 | switch (aEntityData->getKind()) | ||
162 | 243 | { | ||
163 | 244 | case EntityData::SCHEMA: | ||
164 | 245 | lDataKind = "schema"; | ||
165 | 246 | break; | ||
166 | 247 | case EntityData::MODULE: | ||
167 | 248 | lDataKind = "module"; | ||
168 | 249 | break; | ||
169 | 250 | default: | ||
170 | 251 | break; | ||
171 | 252 | } | ||
172 | 253 | |||
173 | 254 | //construct the arguments for the url resolver | ||
174 | 255 | std::vector<ItemSequence_t> lArgs; | ||
175 | 256 | ItemSequence_t lSeq0 = new SingletonItemSequence(theFunction); | ||
176 | 257 | ItemSequence_t lSeq1 = new SingletonItemSequence(XQXQModule::getItemFactory()->createString(aUri)); | ||
177 | 258 | ItemSequence_t lSeq2 = new SingletonItemSequence(XQXQModule::getItemFactory()->createString(lDataKind)); | ||
178 | 259 | lArgs.push_back(lSeq0); | ||
179 | 260 | lArgs.push_back(lSeq1); | ||
180 | 261 | lArgs.push_back(lSeq2); | ||
181 | 262 | |||
182 | 263 | //invoke the HOF helper function using the arguments generated | ||
183 | 264 | Item lHofHelper = XQXQModule::getItemFactory()->createQName("http://www.zorba-xquery.com/modules/xqxq", "xqxq", "hof-invoker"); | ||
184 | 265 | ItemSequence_t lResult = theCtx->invoke(lHofHelper, lArgs); | ||
185 | 266 | |||
186 | 267 | //Check if the result is an empty sequence by creating an Iterator, this is cheaper than serializing the result | ||
187 | 268 | //and then checking if it was empty. | ||
188 | 269 | Iterator_t lIter = lResult->getIterator(); | ||
189 | 270 | Item lItem; | ||
190 | 271 | lIter->open(); | ||
191 | 272 | while (lIter->next(lItem)) | ||
192 | 273 | { | ||
193 | 274 | std::cout << lItem.getStringValue() << std::endl; | ||
194 | 275 | oUris.push_back(lItem.getStringValue()); | ||
195 | 276 | } | ||
196 | 277 | lIter->close(); | ||
197 | 278 | |||
198 | 279 | } | ||
199 | 280 | |||
200 | 281 | |||
201 | 282 | Resource* | ||
202 | 283 | PrepareMainModuleFunction::XQXQURLResolver::resolveURL( | ||
203 | 284 | const String& aUrl, | ||
204 | 285 | EntityData const* aEntityData) | ||
205 | 286 | { | ||
206 | 287 | //Create entityData string to send to the new url resolver | ||
207 | 288 | String lDataKind; | ||
208 | 289 | switch (aEntityData->getKind()) | ||
209 | 290 | { | ||
210 | 291 | case EntityData::SCHEMA: | ||
211 | 292 | lDataKind = "schema"; | ||
212 | 293 | break; | ||
213 | 294 | case EntityData::MODULE: | ||
214 | 295 | lDataKind = "module"; | ||
215 | 296 | break; | ||
216 | 297 | default: | ||
217 | 298 | break; | ||
218 | 299 | } | ||
219 | 300 | |||
220 | 301 | //construct the arguments for the url resolver | ||
221 | 302 | std::vector<ItemSequence_t> lArgs; | ||
222 | 303 | ItemSequence_t lSeq0 = new SingletonItemSequence(theFunction); | ||
223 | 304 | ItemSequence_t lSeq1 = new SingletonItemSequence(XQXQModule::getItemFactory()->createString(aUrl)); | ||
224 | 305 | ItemSequence_t lSeq2 = new SingletonItemSequence(XQXQModule::getItemFactory()->createString(lDataKind)); | ||
225 | 306 | lArgs.push_back(lSeq0); | ||
226 | 307 | lArgs.push_back(lSeq1); | ||
227 | 308 | lArgs.push_back(lSeq2); | ||
228 | 309 | |||
229 | 310 | //invoke the HOF helper function using the arguments generated | ||
230 | 311 | Item lHofHelper = XQXQModule::getItemFactory()->createQName("http://www.zorba-xquery.com/modules/xqxq", "xqxq", "hof-invoker"); | ||
231 | 312 | ItemSequence_t lResult = theCtx->invoke(lHofHelper, lArgs); | ||
232 | 313 | |||
233 | 314 | //Check if the result is an empty sequence by creating an Iterator, this is cheaper than serializing the result | ||
234 | 315 | //and then checking if it was empty. | ||
235 | 316 | Iterator_t lIter = lResult->getIterator(); | ||
236 | 317 | Item lItem; | ||
237 | 318 | lIter->open(); | ||
238 | 319 | lIter->next(lItem); | ||
239 | 320 | lIter->close(); | ||
240 | 321 | if (lItem.isNull()) | ||
241 | 322 | return NULL; | ||
242 | 323 | |||
243 | 324 | //Serialize resulting sequence of the resolver | ||
244 | 325 | Zorba_SerializerOptions_t lOpt; | ||
245 | 326 | if (lItem.isNode()) | ||
246 | 327 | lOpt.ser_method = ZORBA_SERIALIZATION_METHOD_XML; | ||
247 | 328 | else | ||
248 | 329 | lOpt.ser_method = ZORBA_SERIALIZATION_METHOD_TEXT; | ||
249 | 330 | lOpt.omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES; | ||
250 | 331 | Serializer_t lSer = Serializer::createSerializer(lOpt); | ||
251 | 332 | std::stringstream lSerResult; | ||
252 | 333 | lSer->serialize(lResult, lSerResult); | ||
253 | 334 | |||
254 | 335 | //return resource | ||
255 | 336 | return StreamResource::create(new std::istringstream(lSerResult.str()), &streamReleaser); | ||
256 | 337 | } | ||
257 | 338 | |||
258 | 229 | zorba::ItemSequence_t | 339 | zorba::ItemSequence_t |
259 | 230 | PrepareMainModuleFunction::evaluate( | 340 | PrepareMainModuleFunction::evaluate( |
260 | 231 | const Arguments_t& aArgs, | 341 | const Arguments_t& aArgs, |
261 | @@ -233,6 +343,8 @@ | |||
262 | 233 | const zorba::DynamicContext* aDctx) const | 343 | const zorba::DynamicContext* aDctx) const |
263 | 234 | { | 344 | { |
264 | 235 | DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx); | 345 | DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx); |
265 | 346 | StaticContext_t lSctxChild = aSctx->createChildContext(); | ||
266 | 347 | StaticContext_t lMapperSctx = aSctx->createChildContext(); | ||
267 | 236 | 348 | ||
268 | 237 | QueryMap* lQueryMap; | 349 | QueryMap* lQueryMap; |
269 | 238 | if(!(lQueryMap = dynamic_cast<QueryMap*>(lDynCtx->getExternalFunctionParameter("xqxqQueryMap")))) | 350 | if(!(lQueryMap = dynamic_cast<QueryMap*>(lDynCtx->getExternalFunctionParameter("xqxqQueryMap")))) |
270 | @@ -247,9 +359,34 @@ | |||
271 | 247 | 359 | ||
272 | 248 | XQuery_t lQuery; | 360 | XQuery_t lQuery; |
273 | 249 | 361 | ||
274 | 362 | StaticContext_t ltempSctx = lZorba->createStaticContext(); | ||
275 | 363 | XQXQURLResolver* lResolver = NULL; | ||
276 | 364 | XQXQURIMapper* lMapper = NULL; | ||
277 | 365 | |||
278 | 366 | if ( aArgs.size() > 2 ) | ||
279 | 367 | { | ||
280 | 368 | Item lMapperFunctionItem = getItemArgument(aArgs, 2); | ||
281 | 369 | if (!lMapperFunctionItem.isNull()) | ||
282 | 370 | { | ||
283 | 371 | lMapper = new XQXQURIMapper(lMapperFunctionItem, lSctxChild); | ||
284 | 372 | ltempSctx->registerURIMapper(lMapper); | ||
285 | 373 | } | ||
286 | 374 | } | ||
287 | 375 | |||
288 | 376 | if ( aArgs.size() > 1 ) | ||
289 | 377 | { | ||
290 | 378 | Item lResolverFunctionItem = getItemArgument(aArgs, 1); | ||
291 | 379 | if (!lResolverFunctionItem.isNull()) | ||
292 | 380 | { | ||
293 | 381 | lResolver = new XQXQURLResolver(lResolverFunctionItem, lSctxChild); | ||
294 | 382 | ltempSctx->registerURLResolver(lResolver); | ||
295 | 383 | } | ||
296 | 384 | |||
297 | 385 | } | ||
298 | 386 | |||
299 | 250 | try | 387 | try |
300 | 251 | { | 388 | { |
302 | 252 | lQuery = lZorba->compileQuery(lQueryString); | 389 | lQuery = lZorba->compileQuery(lQueryString, ltempSctx); |
303 | 253 | } | 390 | } |
304 | 254 | catch (XQueryException& xe) | 391 | catch (XQueryException& xe) |
305 | 255 | { | 392 | { |
306 | @@ -277,12 +414,18 @@ | |||
307 | 277 | lStream << lUUID; | 414 | lStream << lUUID; |
308 | 278 | 415 | ||
309 | 279 | String lStrUUID = lStream.str(); | 416 | String lStrUUID = lStream.str(); |
310 | 417 | |||
311 | 418 | lQueryMap->storeQuery(lStrUUID, lQuery); | ||
312 | 280 | 419 | ||
314 | 281 | lQueryMap->storeQuery(lStrUUID, lQuery); | 420 | if (lResolver) |
315 | 421 | delete lResolver; | ||
316 | 422 | if (lMapper) | ||
317 | 423 | delete lMapper; | ||
318 | 282 | 424 | ||
319 | 283 | return ItemSequence_t(new SingletonItemSequence(XQXQModule::getItemFactory()->createAnyURI(lStrUUID))); | 425 | return ItemSequence_t(new SingletonItemSequence(XQXQModule::getItemFactory()->createAnyURI(lStrUUID))); |
320 | 284 | } | 426 | } |
321 | 285 | 427 | ||
322 | 428 | |||
323 | 286 | /******************************************************************************************* | 429 | /******************************************************************************************* |
324 | 287 | *******************************************************************************************/ | 430 | *******************************************************************************************/ |
325 | 288 | zorba::ItemSequence_t | 431 | zorba::ItemSequence_t |
326 | 289 | 432 | ||
327 | === modified file 'src/xqxq.xq.src/xqxq.h' | |||
328 | --- src/xqxq.xq.src/xqxq.h 2012-10-01 17:54:38 +0000 | |||
329 | +++ src/xqxq.xq.src/xqxq.h 2012-10-19 01:25:26 +0000 | |||
330 | @@ -49,6 +49,7 @@ | |||
331 | 49 | 49 | ||
332 | 50 | }; | 50 | }; |
333 | 51 | 51 | ||
334 | 52 | |||
335 | 52 | class QueryMap : public ExternalFunctionParameter{ | 53 | class QueryMap : public ExternalFunctionParameter{ |
336 | 53 | private: | 54 | private: |
337 | 54 | typedef std::map<String, XQuery_t> QueryMap_t; | 55 | typedef std::map<String, XQuery_t> QueryMap_t; |
338 | @@ -117,7 +118,7 @@ | |||
339 | 117 | public: | 118 | public: |
340 | 118 | PrepareMainModuleFunction(const XQXQModule* aModule) : XQXQFunction(aModule) {} | 119 | PrepareMainModuleFunction(const XQXQModule* aModule) : XQXQFunction(aModule) {} |
341 | 119 | 120 | ||
343 | 120 | virtual ~PrepareMainModuleFunction(){} | 121 | virtual ~PrepareMainModuleFunction(){ } |
344 | 121 | 122 | ||
345 | 122 | virtual zorba::String | 123 | virtual zorba::String |
346 | 123 | getLocalName() const { return "prepare-main-module"; } | 124 | getLocalName() const { return "prepare-main-module"; } |
347 | @@ -126,6 +127,43 @@ | |||
348 | 126 | evaluate(const Arguments_t&, | 127 | evaluate(const Arguments_t&, |
349 | 127 | const zorba::StaticContext*, | 128 | const zorba::StaticContext*, |
350 | 128 | const zorba::DynamicContext*) const; | 129 | const zorba::DynamicContext*) const; |
351 | 130 | |||
352 | 131 | protected: | ||
353 | 132 | |||
354 | 133 | class XQXQURLResolver : public URLResolver | ||
355 | 134 | { | ||
356 | 135 | protected: | ||
357 | 136 | Item theFunction; | ||
358 | 137 | StaticContext_t theCtx; | ||
359 | 138 | |||
360 | 139 | public: | ||
361 | 140 | XQXQURLResolver(Item& aFunction, StaticContext_t& aSctx) : URLResolver(), theFunction(aFunction), theCtx(aSctx) {} | ||
362 | 141 | |||
363 | 142 | virtual ~XQXQURLResolver(){ } | ||
364 | 143 | |||
365 | 144 | virtual Resource* resolveURL(const String& aUrl, | ||
366 | 145 | EntityData const* aEntityData); | ||
367 | 146 | |||
368 | 147 | }; | ||
369 | 148 | |||
370 | 149 | class XQXQURIMapper : public URIMapper | ||
371 | 150 | { | ||
372 | 151 | protected: | ||
373 | 152 | Item theFunction; | ||
374 | 153 | StaticContext_t theCtx; | ||
375 | 154 | |||
376 | 155 | public: | ||
377 | 156 | XQXQURIMapper(Item& aFunction, StaticContext_t& aSctx) : URIMapper(), theFunction(aFunction), theCtx(aSctx) {} | ||
378 | 157 | |||
379 | 158 | virtual ~XQXQURIMapper(){ } | ||
380 | 159 | |||
381 | 160 | virtual void mapURI( | ||
382 | 161 | const zorba::String aUri, | ||
383 | 162 | EntityData const* aEntityData, | ||
384 | 163 | std::vector<zorba::String>& oUris); | ||
385 | 164 | |||
386 | 165 | }; | ||
387 | 166 | |||
388 | 129 | }; | 167 | }; |
389 | 130 | 168 | ||
390 | 131 | class PrepareLibraryModuleFunction : public XQXQFunction{ | 169 | class PrepareLibraryModuleFunction : public XQXQFunction{ |
391 | 132 | 170 | ||
392 | === added file 'test/ExpQueryResults/xqxq/uri-mapper.xml.res' | |||
393 | --- test/ExpQueryResults/xqxq/uri-mapper.xml.res 1970-01-01 00:00:00 +0000 | |||
394 | +++ test/ExpQueryResults/xqxq/uri-mapper.xml.res 2012-10-19 01:25:26 +0000 | |||
395 | @@ -0,0 +1,2 @@ | |||
396 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
397 | 2 | foo | ||
398 | 0 | 3 | ||
399 | === added file 'test/ExpQueryResults/xqxq/uri-mapper2.xml.res' | |||
400 | --- test/ExpQueryResults/xqxq/uri-mapper2.xml.res 1970-01-01 00:00:00 +0000 | |||
401 | +++ test/ExpQueryResults/xqxq/uri-mapper2.xml.res 2012-10-19 01:25:26 +0000 | |||
402 | @@ -0,0 +1,2 @@ | |||
403 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
404 | 2 | <test:test xmlns:test="http://test"><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test> | ||
405 | 0 | 3 | ||
406 | === added file 'test/ExpQueryResults/xqxq/url-module-resolver.xml.res' | |||
407 | --- test/ExpQueryResults/xqxq/url-module-resolver.xml.res 1970-01-01 00:00:00 +0000 | |||
408 | +++ test/ExpQueryResults/xqxq/url-module-resolver.xml.res 2012-10-19 01:25:26 +0000 | |||
409 | @@ -0,0 +1,2 @@ | |||
410 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
411 | 2 | foo | ||
412 | 0 | 3 | ||
413 | === added file 'test/ExpQueryResults/xqxq/url-schema-resolver.xml.res' | |||
414 | --- test/ExpQueryResults/xqxq/url-schema-resolver.xml.res 1970-01-01 00:00:00 +0000 | |||
415 | +++ test/ExpQueryResults/xqxq/url-schema-resolver.xml.res 2012-10-19 01:25:26 +0000 | |||
416 | @@ -0,0 +1,2 @@ | |||
417 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
418 | 2 | <test:test xmlns:test="http://test"><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test> | ||
419 | 0 | 3 | ||
420 | === added file 'test/ExpQueryResults/xqxq/url-schema-resolver2.xml.res' | |||
421 | --- test/ExpQueryResults/xqxq/url-schema-resolver2.xml.res 1970-01-01 00:00:00 +0000 | |||
422 | +++ test/ExpQueryResults/xqxq/url-schema-resolver2.xml.res 2012-10-19 01:25:26 +0000 | |||
423 | @@ -0,0 +1,2 @@ | |||
424 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
425 | 2 | <test:test xmlns:test="http://test"><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test> | ||
426 | 0 | 3 | ||
427 | === added file 'test/Queries/xqxq/test.xsd' | |||
428 | --- test/Queries/xqxq/test.xsd 1970-01-01 00:00:00 +0000 | |||
429 | +++ test/Queries/xqxq/test.xsd 2012-10-19 01:25:26 +0000 | |||
430 | @@ -0,0 +1,14 @@ | |||
431 | 1 | <?xml version="1.0"?> | ||
432 | 2 | <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" | ||
433 | 3 | targetNamespace="http://test" | ||
434 | 4 | xmlns="http://test" | ||
435 | 5 | elementFormDefault="qualified"> | ||
436 | 6 | <xs:element name="test"> | ||
437 | 7 | <xs:complexType> | ||
438 | 8 | <xs:sequence> | ||
439 | 9 | <xs:element name="subtest" type="xs:string"/> | ||
440 | 10 | <xs:element name="subtest2" type="xs:string"/> | ||
441 | 11 | </xs:sequence> | ||
442 | 12 | </xs:complexType> | ||
443 | 13 | </xs:element> | ||
444 | 14 | </xs:schema> | ||
445 | 0 | \ No newline at end of file | 15 | \ No newline at end of file |
446 | 1 | 16 | ||
447 | === added file 'test/Queries/xqxq/uri-mapper.xq' | |||
448 | --- test/Queries/xqxq/uri-mapper.xq 1970-01-01 00:00:00 +0000 | |||
449 | +++ test/Queries/xqxq/uri-mapper.xq 2012-10-19 01:25:26 +0000 | |||
450 | @@ -0,0 +1,27 @@ | |||
451 | 1 | import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | ||
452 | 2 | |||
453 | 3 | declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver'; | ||
454 | 4 | declare namespace mapper = 'http://www.zorba-xquery.com/modules/xqxq/uri-mapper'; | ||
455 | 5 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
456 | 6 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
457 | 7 | declare option op:enable "f:hof"; | ||
458 | 8 | |||
459 | 9 | declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) { | ||
460 | 10 | if($namespace = 'http://foo') | ||
461 | 11 | then "module namespace test = 'http://test'; declare function test:foo(){'foo'};" | ||
462 | 12 | else () | ||
463 | 13 | }; | ||
464 | 14 | |||
465 | 15 | declare function mapper:uri-mapper($namespace as xs:string, $entity as xs:string) | ||
466 | 16 | { | ||
467 | 17 | if($namespace = 'http://test') | ||
468 | 18 | then 'http://foo' | ||
469 | 19 | else () | ||
470 | 20 | }; | ||
471 | 21 | |||
472 | 22 | variable $queryID := xqxq:prepare-main-module | ||
473 | 23 | ( | ||
474 | 24 | "import module namespace test = 'http://test'; test:foo()", | ||
475 | 25 | resolver:url-resolver#2, mapper:uri-mapper#2 | ||
476 | 26 | ); | ||
477 | 27 | xqxq:evaluate($queryID) | ||
478 | 0 | 28 | ||
479 | === added file 'test/Queries/xqxq/uri-mapper2.xq' | |||
480 | --- test/Queries/xqxq/uri-mapper2.xq 1970-01-01 00:00:00 +0000 | |||
481 | +++ test/Queries/xqxq/uri-mapper2.xq 2012-10-19 01:25:26 +0000 | |||
482 | @@ -0,0 +1,22 @@ | |||
483 | 1 | import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | ||
484 | 2 | |||
485 | 3 | declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver'; | ||
486 | 4 | declare namespace mapper = 'http://www.zorba-xquery.com/modules/xqxq/uri-mapper'; | ||
487 | 5 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
488 | 6 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
489 | 7 | declare option op:enable "f:hof"; | ||
490 | 8 | |||
491 | 9 | declare function mapper:uri-mapper($namespace as xs:string, $entity as xs:string) | ||
492 | 10 | { | ||
493 | 11 | if ($namespace = 'http://test' and $entity = 'schema') | ||
494 | 12 | then resolve-uri('test.xsd') | ||
495 | 13 | else () | ||
496 | 14 | }; | ||
497 | 15 | |||
498 | 16 | variable $queryID := xqxq:prepare-main-module | ||
499 | 17 | ( | ||
500 | 18 | "import schema namespace test = 'http://test'; validate{<test:test><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test>}", | ||
501 | 19 | (), | ||
502 | 20 | mapper:uri-mapper#2 | ||
503 | 21 | ); | ||
504 | 22 | xqxq:evaluate($queryID) | ||
505 | 0 | 23 | ||
506 | === added file 'test/Queries/xqxq/url-module-resolver.xq' | |||
507 | --- test/Queries/xqxq/url-module-resolver.xq 1970-01-01 00:00:00 +0000 | |||
508 | +++ test/Queries/xqxq/url-module-resolver.xq 2012-10-19 01:25:26 +0000 | |||
509 | @@ -0,0 +1,17 @@ | |||
510 | 1 | import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | ||
511 | 2 | |||
512 | 3 | declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver'; | ||
513 | 4 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
514 | 5 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
515 | 6 | declare option op:enable "f:hof"; | ||
516 | 7 | |||
517 | 8 | declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) { | ||
518 | 9 | if($namespace = 'http://test.xq') | ||
519 | 10 | then "module namespace test = 'http://test'; declare function test:foo(){'foo'};" | ||
520 | 11 | else () | ||
521 | 12 | }; | ||
522 | 13 | |||
523 | 14 | variable $queryID := xqxq:prepare-main-module( | ||
524 | 15 | "import module namespace test = 'http://test'; test:foo()", | ||
525 | 16 | resolver:url-resolver#2, ()); | ||
526 | 17 | xqxq:evaluate($queryID) | ||
527 | 0 | 18 | ||
528 | === added file 'test/Queries/xqxq/url-schema-resolver.xq' | |||
529 | --- test/Queries/xqxq/url-schema-resolver.xq 1970-01-01 00:00:00 +0000 | |||
530 | +++ test/Queries/xqxq/url-schema-resolver.xq 2012-10-19 01:25:26 +0000 | |||
531 | @@ -0,0 +1,20 @@ | |||
532 | 1 | import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | ||
533 | 2 | |||
534 | 3 | declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver'; | ||
535 | 4 | |||
536 | 5 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
537 | 6 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
538 | 7 | declare option op:enable "f:hof"; | ||
539 | 8 | |||
540 | 9 | declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) { | ||
541 | 10 | if($namespace = 'http://test' and $entity = 'schema') | ||
542 | 11 | then | ||
543 | 12 | doc('test.xsd') | ||
544 | 13 | else | ||
545 | 14 | () | ||
546 | 15 | }; | ||
547 | 16 | |||
548 | 17 | variable $queryID := xqxq:prepare-main-module( | ||
549 | 18 | "import schema namespace test = 'http://test'; validate {<test:test><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test>}", | ||
550 | 19 | resolver:url-resolver#2, ()); | ||
551 | 20 | xqxq:evaluate($queryID) | ||
552 | 0 | 21 | ||
553 | === added file 'test/Queries/xqxq/url-schema-resolver2.xq' | |||
554 | --- test/Queries/xqxq/url-schema-resolver2.xq 1970-01-01 00:00:00 +0000 | |||
555 | +++ test/Queries/xqxq/url-schema-resolver2.xq 2012-10-19 01:25:26 +0000 | |||
556 | @@ -0,0 +1,29 @@ | |||
557 | 1 | import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq'; | ||
558 | 2 | |||
559 | 3 | import module namespace ddl = | ||
560 | 4 | "http://www.zorba-xquery.com/modules/store/dynamic/collections/w3c/ddl"; | ||
561 | 5 | import module namespace dml = | ||
562 | 6 | "http://www.zorba-xquery.com/modules/store/dynamic/collections/w3c/dml"; | ||
563 | 7 | |||
564 | 8 | declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver'; | ||
565 | 9 | declare namespace op = "http://www.zorba-xquery.com/options/features"; | ||
566 | 10 | declare namespace f = "http://www.zorba-xquery.com/features"; | ||
567 | 11 | declare option op:enable "f:hof"; | ||
568 | 12 | |||
569 | 13 | declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) { | ||
570 | 14 | if ($entity = 'schema') | ||
571 | 15 | then | ||
572 | 16 | dml:collection("http://www.zorba-xquery.com/modules/xqxq")//xs:schema[@targetNamespace=$namespace] | ||
573 | 17 | else | ||
574 | 18 | () | ||
575 | 19 | }; | ||
576 | 20 | |||
577 | 21 | declare variable $coll := "http://www.zorba-xquery.com/modules/xqxq"; | ||
578 | 22 | declare variable $schema := doc("test.xsd"); | ||
579 | 23 | ddl:create($coll); | ||
580 | 24 | |||
581 | 25 | dml:apply-insert-nodes-first($coll, $schema); | ||
582 | 26 | variable $query-key := xqxq:prepare-main-module( | ||
583 | 27 | "import schema namespace test = 'http://test'; validate {<test:test><test:subtest>a</test:subtest><test:subtest2>a</test:subtest2></test:test>}", | ||
584 | 28 | resolver:url-resolver#2, ()); | ||
585 | 29 | xqxq:evaluate($query-key) |
There is a memory leak in the implementation.
To check simply run Temporary/ LastTest. log.
ctest -R url-
and look into the build/Testing/
Here is what you will see:
test xqxq/url- schema- resolver www.zorba- xquery. com/modules/ xqxq/url- resolver www.zorba- xquery. com/modules/ xqxq :ZorbaException ' www.zorba- xquery. com/html/ documentation in section General Architecture -> Memory Leaks.
[...]
=== end of result ===
testdriver: success (non-canonical result # 1 matches)
testdriver: test runtime was 37041us
testdriver: success
ID: 78 Referenced URI: http://
ID: 113 Referenced URI: http://
terminate called after throwing an instance of 'zorba:
what(): Zorba did not close properly, objects may still in memory.
2 referenced URI(s) remain in the string pool.
For help avoiding this message please refer to http://