I will try to describe our situation a little bit more clearly.
This is focused on our development environment, but similar situations occur in a production environment.

 

We have multiple developers, each working on multiple projects.
Each project will require a database.

Each database will need to be accessed by multiple applications.
Applications may be developed and executed by multiple developers on a netwok.
We want to have a central server so that all developers are connecting to a single location.

 

The content in each of these databases may be similar but with some structural (schema) differences.

As such, any queries for interacting with the data may be implemented slightly differently.

 

When a new project is started, we would have a developer create an associated database on the central server.

We would like to create associated queries/functions to access the data for this new project.
These would only be applicable to the database we just created, so we would not want them executed on another database.
They also may conflict with similar functions for other project databases, so keeping them isolated is ideal.

 

From the suggestions, it sounds like storing the queries as data within the database is the most likely solution in the current software.

It does mean we lose some of the benefits of them being actual modules.

 

As per Christian’s response, the software would need modifications to allow these isolated modules.

I would expect some isolated directory structure per database would be necessary (if utilised).
I would also expect this to be used in conjunction to the current global modules (probably less concerned about how the implementation would end up).

 

Cheers,
Chris

 

From: Majewski, Steven Dennis (sdm7g) <sdm7g@virginia.edu>
Sent: Wednesday, 26 February 2020 4:21 AM
To: DYER Chris <Chris.Dyer@sydac.com>
Cc: basex-talk@mailman.uni-konstanz.de
Subject: Re: [basex-talk] Database specific xquery modules

 

Also, question for the OP (Chris): 

 

 

It’s not completely clear what exactly you want to hide from whom.

 

That is, if you only want to hide the implementation details from API clients, then RESTXQ and some conditional code is probably sufficient, however your comparison with local stored procedures in SQL make me think you mean that database clients my provide their own implementations of lower level functions, and you want higher level procedures to be able to call those functions without being concerned with the implementations. ( Which is what made me think of comparison with Object Oriented programming. ) 

 

— Steve M. 

 



On Feb 25, 2020, at 11:17 AM, Majewski, Steven Dennis (sdm7g) <sdm7g@virginia.edu> wrote:

 

I was thinking that there would be a simpler way to bind function namespaces and databases, but that runs into the asymmetry that string in  import and namespace declarations in the prolog must be literal strings and can’t be variables. ( I still tend to think from XSLT mental models instead of XQuery sometimes. ) And it seems that even the extended Q{} syntax requires a literal, so it’s not simple to make the function namespace variable. 

 

I can do something like this ( with modules for English, French, Italian added to my repo ):

 

declare variable $it := 'http://example.org/modules/Italian' ;

declare variable $fr := 'http://example.org/modules/French' ;

declare variable $head := 'import module namespace lang = "' ;

declare variable $tail :=  '";  ' ;

 

for $lang in ( $it, $fr )

let $prolog := $head || $lang || $tail 

return xquery:eval( $prolog || 'lang:hello("Everybody!")' ) 

 

 

Returns =>

 

Ciao Everybody!

Bonjour Everybody!

 

In the XSLT 1 days, we used to get around the lack of dynamic eval by the functional programming technique of having one stylesheet produce another with the variables resolved. 

So another way of packaging this might be to create a RESTXQ endpoint that generates an XQuery module from a template and use that endpoint URL in an “import module … at” expression. But that location must also be a literal, so it’s just another variation of the above. 

 

I can also think of some tricks using higher level functions, but so far, nothing that makes it all simple. 

 

 

— Steve M. 

 



On Feb 25, 2020, at 5:50 AM, Christian Grün <christian.gruen@gmail.com> wrote:

 

Hi Luke,


It isn't clear to me how RESTXQ helps with this.


Here is a (very minimal) example how an XQuery endpoint could look like:

 declare
   %rest:path('{$db}/{$query}')
 function rest:execute(
   $db as xs:string,
   $query as xs:string
 ) {
   xquery:eval(
     xs:anyURI($db || '/' || $query),
     map { '': db:open($db) }
   )
 };

One endpoint for all databases would suffice indeed.

Extending the semantics of our REST API would be another option, but
we may need to clarify various questions (will there be an extra
server directory for each database? What happens if people want to
access both global and database-specific queries? etc).

Hope this helps,
Christian