namespaced entities

This commit is contained in:
Andy Bunce 2020-09-04 12:24:15 +01:00
parent dde1fa6e82
commit 50f8daa2f3
19 changed files with 98 additions and 96 deletions

View File

@ -1,4 +1,4 @@
<entity name="entity" xmlns="https://github.com/Quodatum/app-doc/entity">
<entity name="dice.entity" xmlns="https://github.com/Quodatum/app-doc/entity">
<description>List of Entities i.e. things described in this framework
</description>
<namespace prefix="ent"

View File

@ -1,4 +1,4 @@
<entity name="entity.field" xmlns="https://github.com/Quodatum/app-doc/entity">
<entity name="dice.field" xmlns="https://github.com/Quodatum/app-doc/entity">
<description>About an entity field. </description>
<namespace prefix="ent"
uri="https://github.com/Quodatum/app-doc/entity" />

View File

@ -71,7 +71,7 @@
var data={message: this.message,
type: this.type,
checkbox: this.checkbox};
HTTP.post("log/add",Qs.stringify(data))
HTTP.post("basex.log/add",Qs.stringify(data))
.then(r=>{
console.log("submit: ",data);
if(this.checkbox){

View File

@ -63,6 +63,7 @@
:search="search"
class="elevation-1"
no-data-text="No logs found"
sort-by= "time"
v-bind:options.sync="pagination"
>
<template slot="items" slot-scope="props">
@ -95,7 +96,7 @@
{ text: 'address', value: 'address' },
],
items:[],
pagination:{sortBy: 'time',descending:true,rowsPerPage:25},
pagination:{ rowsPerPage:25},
selected:[],
search:"",
loading:false,

View File

@ -7,12 +7,12 @@ import module namespace web = 'quodatum.web.utils4' at "../../lib/webutils.xqm";
: show active log
:)
declare
%rest:GET %rest:path("/vue-poc/api/log")
%rest:GET %rest:path("/vue-poc/api/basex.log")
%output:method("json")
function j:list()
as element(json)
{
let $entity:=$entity:list("basexlog")
let $entity:=$entity:list("basex.log")
let $items:=$entity("data")()
let $items:=$items[false() or not(ends-with(. ,"/vue-poc/api/log"))]
(: let $_:=admin:write-log("hello admin:write-log") :)
@ -44,7 +44,7 @@ as element(json)
: create a log entry
:)
declare
%rest:POST %rest:path("/vue-poc/api/log/add")
%rest:POST %rest:path("/vue-poc/api/basex.log/add")
%rest:form-param("type", "{$type}")
%rest:form-param("message", "{$message}")
%output:method("text")

View File

@ -31,7 +31,7 @@
:loading="loading"
:disabled="loading"
><v-icon>refresh</v-icon></v-btn>
<vp-entitylink entity="entity"></vp-entitylink>
<vp-entitylink entity="dice.entity"></vp-entitylink>
</v-toolbar>
</template>

View File

@ -78,7 +78,7 @@
</v-layout>
</v-expansion-panel-header>
<v-expansion-panel-content>
<qd-table :headers="headers" :data-uri='"data/entity/"+entity +"/field"' entity="entity.field" no-data-msg="Nothing found">
<qd-table :headers="headers" :data-uri='"data/entity/"+entity +"/field"' entity="dice.field" no-data-msg="Nothing found">
</qd-table>
</v-expansion-panel-content>
</v-expansion-panel>

View File

@ -24,7 +24,7 @@ declare
%rest:query-param("q", "{$q}")
%output:method("json")
function model-list($q) {
let $entity:=$entity:list("entity")
let $entity:=$entity:list("dice.entity")
let $items:=$entity?data()
let $items:=if($q)then $items[fn:contains($entity("access")("name")(.),$q)] else $items
return dice:response($items,$entity,web:dice())
@ -55,7 +55,7 @@ declare
%rest:produces("application/json")
%output:method("json")
function model($entity) {
let $this:=$entity:list("entity")
let $this:=$entity:list("dice.entity")
let $items:=$this?data()
let $fields:=$this?json
let $item:=$items[@name=$entity]
@ -72,7 +72,7 @@ declare
%rest:produces("text/xml;qs=0.8")
%output:method("xml")
function model2($entity) {
let $this:=$entity:list("entity")
let $this:=$entity:list("dice.entity")
let $items:=$this?data()
let $fields:=$this?json
let $item:=$items[@name=$entity]
@ -88,10 +88,10 @@ declare
%rest:GET %rest:path("vue-poc/api/data/entity/{$entity}/field")
%output:method("json")
function field-list($entity) {
let $dentity:=$entity:list("entity")
let $dentity:=$entity:list("dice.entity")
let $items:=$dentity?data()
let $items:=$items[@name=$entity]/ent:fields/ent:field
let $fentity:=$entity:list("entity.field")
let $fentity:=$entity:list("dice.field")
return dice:response($items,$fentity,web:dice())
};

View File

@ -2,14 +2,13 @@
: generate xquery access code for entity definitions
:)
module namespace bf = 'quodatum.tools.buildfields';
declare default function namespace 'quodatum.tools.buildfields';
declare namespace ent="https://github.com/Quodatum/app-doc/entity";
(:~
: generate xquery module for given entities as a string
:)
declare function module($entities as element(ent:entity)*,$imports)
declare function bf:module($entities as element(ent:entity)*,$imports)
as xs:string
{
let $src:= <text>(: entity access maps
@ -36,14 +35,14 @@ as map(*){{
(:~
: generate xquery for to return field value in the format: "name":function($_){}
:)
declare function accessfn($f as element(ent:field)) as xs:string
declare function bf:accessfn($f as element(ent:field)) as xs:string
{
let $type:=$f/@type/fn:string()
return <field>
"{$f/@name/fn:string()}": function($_ as element()) as {$type} {{$_/{$f/ent:xpath } }}</field>
};
declare function generate($e as element(ent:entity)) as xs:string
declare function bf:generate($e as element(ent:entity)) as xs:string
{
let $fields:=for $field in $e/ent:fields/ent:field
order by $field/@name
@ -55,14 +54,14 @@ declare function generate($e as element(ent:entity)) as xs:string
return <field>
"{$e/@name/fn:string()}": map{{
"name": "{ $e/@name/fn:string()}",
"description": "{ escape($e/ent:description)}",
"access": map{{ {$fields!accessfn(.)=>fn:string-join(",")} }},
"description": "{ bf:escape($e/ent:description)}",
"access": map{{ {$fields!bf:accessfn(.)=>fn:string-join(",")} }},
"filter": function($item,$q) as xs:boolean{{
some $e in ( {fn:string-join($filter,", ")}) satisfies
fn:contains($e,$q, 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive')
}},
"json": map{{ {$fields!jsonfn(.)=>fn:string-join(",")} }},
"json": map{{ {$fields!bf:jsonfn(.)=>fn:string-join(",")} }},
"data": function() as {$e/ent:data/@type/fn:string(.)}*
{{ {let $a:=$e/ent:data/fn:string() return if($a)then $a else "()"} }},
@ -76,23 +75,24 @@ declare function generate($e as element(ent:entity)) as xs:string
(:~
: @return sequence of element(entity) items for definitions at path
:)
declare function entities($path as xs:string)
declare function bf:entities($path as xs:string)
as element(ent:entity)*
{
let $_:=fn:trace($path,"DD")
let $p:=fn:resolve-uri($path) || "/"
return for $f in file:list($p)
return for $f in file:list($p,fn:true())
where not(ends-with(trace($f),file:dir-separator()))
order by $f
return fn:doc(fn:concat($p,$f))/ent:entity
};
(:map for entity :)
declare function build-map($entity as element(ent:entity))
declare function bf:build-map($entity as element(ent:entity))
as xs:string
{
let $m:=for $field in $entity/ent:fields/ent:field
order by $field/@name
return accessfn($field)
return bf:accessfn($field)
return <text>
declare variable $entity:{$entity/@name/fn:string()}: map{{ {fn:string-join($m,",")}
}};
@ -103,14 +103,14 @@ declare variable $entity:{$entity/@name/fn:string()}: map{{ {fn:string-join($m,"
(:~
: return xml for suitable json serialization for field
:)
declare function jsonfn($f as element(ent:field))
declare function bf:jsonfn($f as element(ent:field))
as xs:string
{
let $name:=$f/@name/fn:string()
let $type:=$f/@type/fn:string()
let $opt:=fn:contains($type,"?")
let $repeat:=fn:contains($type,"*")
let $json-type:=json-type($type)
let $json-type:=bf:json-type($type)
let $mult:=if($repeat) then "*" else "?"
let $at:=if($json-type ne "string")
@ -149,7 +149,7 @@ as xs:string
(:~ convert xs type to json
:)
declare function json-type($xsd as xs:string) as xs:string{
declare function bf:json-type($xsd as xs:string) as xs:string{
switch ($xsd)
case "element()" return "string"
case "xs:boolean" return "boolean"
@ -161,28 +161,28 @@ switch ($xsd)
};
(:~ declare any namespaces found :)
declare function build-namespaces($entities as element()*)
declare function bf:build-namespaces($entities as element()*)
{
for $n in distinct-deep($entities/ent:namespace)
for $n in bf:distinct-deep($entities/ent:namespace)
return
<text>declare namespace {$n/@prefix/fn:string()}='{$n/@uri/fn:string()}';
</text>
};
(:~ import any modules found must be in repo :)
declare function build-imports($entities as element()*)
declare function bf:build-imports($entities as element()*)
{
for $n in distinct-deep($entities/ent:module)
for $n in bf:distinct-deep($entities/ent:module)
return
<text>import module namespace {$n/@prefix/fn:string()}='{$n/@namespace/fn:string()}';
</text>
};
declare function build-describe($entities)
declare function bf:build-describe($entities)
as xs:string
{
let $m:=for $e in $entities
return generate($e)
return bf:generate($e)
return <text>
declare variable $entity:list:=map {{ {fn:string-join($m,",")}
}};
@ -190,7 +190,7 @@ declare variable $entity:list:=map {{ {fn:string-join($m,",")}
</text>
};
declare function escape($str as xs:string)
declare function bf:escape($str as xs:string)
as xs:string
{
fn:replace(
@ -200,15 +200,15 @@ as xs:string
(:-----from functx-------------------:)
declare function distinct-deep
declare function bf:distinct-deep
( $nodes as node()* ) as node()* {
for $seq in (1 to fn:count($nodes))
return $nodes[$seq][fn:not(is-node-in-sequence-deep-equal(
return $nodes[$seq][fn:not(bf:is-node-in-sequence-deep-equal(
.,$nodes[fn:position() < $seq]))]
};
declare function is-node-in-sequence-deep-equal
declare function bf:is-node-in-sequence-deep-equal
( $node as node()? ,
$seq as node()* ) as xs:boolean {

View File

@ -6,7 +6,7 @@
:)
module namespace vue-api = 'quodatum:vue.api';
import module namespace bf = 'quodatum.tools.buildfields' at "./../../../lib/entity-gen.xqm";
import module namespace bf = 'quodatum.tools.buildfields' at "entity-gen.xqm";
import module namespace query-a = 'vue-poc/query-a' at "../../../lib/query-a.xqm";
declare variable $vue-api:query:="tx-model.xq";

View File

@ -2,7 +2,7 @@
: Update `generated/models.xqm` from XML files in `data/models`
:)
import module namespace bf = 'quodatum.tools.buildfields' at "./../../../lib/entity-gen.xqm";
import module namespace bf = 'quodatum.tools.buildfields' at "entity-gen.xqm";
(:~
: Folder containing model definitions as xml
@ -20,6 +20,7 @@ declare variable $target as xs:anyURI external
let $config:='import module namespace cfg = "quodatum:media.image.configure" at "features/images/config.xqm";'
let $src:=bf:module(bf:entities($efolder),$config)
return (
prof:variables(),

View File

@ -1,5 +1,5 @@
(: entity access maps
: auto generated from xml files in entities folder at: 2020-07-08T23:08:03.678+01:00
: auto generated from xml files in entities folder at: 2020-09-04T11:37:53.188+01:00
:)
module namespace entity = 'quodatum.models.generated';
@ -244,51 +244,8 @@ hof:top-k-by(admin:logs(), string#1, 2)
}
},
"entity.field": map{
"name": "entity.field",
"description": "About an entity field. ",
"access": map{
"description": function($_ as element()) as xs:string {$_/ent:description },
"name": function($_ as element()) as xs:string {$_/@name },
"parent": function($_ as element()) as xs:string {$_/../../@name },
"type": function($_ as element()) as xs:string {$_/@type },
"xpath": function($_ as element()) as xs:string {$_/ent:xpath } },
"filter": function($item,$q) as xs:boolean{
some $e in ( $item/@name, $item/ent:description) satisfies
fn:contains($e,$q, 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive')
},
"json": map{
"description": function($_ as element()) as element(description)? {
(: xs:string :)
fn:data($_/ent:description)!element description { .}
},
"name": function($_ as element()) as element(name)? {
(: xs:string :)
fn:data($_/@name)!element name { .}
},
"parent": function($_ as element()) as element(parent)? {
(: xs:string :)
fn:data($_/../../@name)!element parent { .}
},
"type": function($_ as element()) as element(type)? {
(: xs:string :)
fn:data($_/@type)!element type { .}
},
"xpath": function($_ as element()) as element(xpath)? {
(: xs:string :)
fn:data($_/ent:xpath)!element xpath { .}
} },
"data": function() as element(ent:field)*
{ collection("doc-doc")/ent:entity/ent:fields/ent:field },
"views": map{
'filter': 'name description'
}
},
"entity": map{
"name": "entity",
"dice.entity": map{
"name": "dice.entity",
"description": "List of Entities i.e. things described in this framework
",
"access": map{
@ -366,6 +323,49 @@ hof:top-k-by(admin:logs(), string#1, 2)
"data": function() as element(ent:entity)*
{ collection("vue-poc")/ent:entity },
"views": map{
'filter': 'name description'
}
},
"dice.field": map{
"name": "dice.field",
"description": "About an entity field. ",
"access": map{
"description": function($_ as element()) as xs:string {$_/ent:description },
"name": function($_ as element()) as xs:string {$_/@name },
"parent": function($_ as element()) as xs:string {$_/../../@name },
"type": function($_ as element()) as xs:string {$_/@type },
"xpath": function($_ as element()) as xs:string {$_/ent:xpath } },
"filter": function($item,$q) as xs:boolean{
some $e in ( $item/@name, $item/ent:description) satisfies
fn:contains($e,$q, 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive')
},
"json": map{
"description": function($_ as element()) as element(description)? {
(: xs:string :)
fn:data($_/ent:description)!element description { .}
},
"name": function($_ as element()) as element(name)? {
(: xs:string :)
fn:data($_/@name)!element name { .}
},
"parent": function($_ as element()) as element(parent)? {
(: xs:string :)
fn:data($_/../../@name)!element parent { .}
},
"type": function($_ as element()) as element(type)? {
(: xs:string :)
fn:data($_/@type)!element type { .}
},
"xpath": function($_ as element()) as element(xpath)? {
(: xs:string :)
fn:data($_/ent:xpath)!element xpath { .}
} },
"data": function() as element(ent:field)*
{ collection("doc-doc")/ent:entity/ent:fields/ent:field },
"views": map{
'filter': 'name description'
}

View File

@ -1,10 +1,10 @@
{
"name": "vue-poc",
"version": "0.5@2020-07-06",
"description": "Frontend vuetify, backend: basex",
"version": "0.5.2@2020-09-04",
"description": "App framework experiments, Frontend vuetify, backend: basex",
"dependencies": {
"ace": "1.4.12",
"vuetify": "2.3.7",
"vuetify": "2.3.10",
"vue": "2.6.11",
"vuex": "3.1.0",
"vue-router": "3.1.6",
@ -15,7 +15,7 @@
"qs": "6.4.0",
"localforage": "1.7.1",
"momentjs": "2.24.0",
"vuetify-jsonschema-form": "0.35.0",
"@koumoul/vjsf": "1.10.0",
"prism": "1.15.0",
"vue-prism-component": "1.1.1",
"vis-timeline-graph2d": "4.20.1",

View File

@ -1,4 +1,4 @@
// generated 2020-09-01T22:40:57.014+01:00
// generated 2020-09-04T12:21:45.271+01:00
// src: file:///C:/Users/andy/git/vue-poc/src/vue-poc/components/qd-autoheight.vue
Vue.component('qd-autoheight',{template:`
@ -2322,7 +2322,7 @@ const Logadd=Vue.extend({template:`
var data={message: this.message,
type: this.type,
checkbox: this.checkbox};
HTTP.post("log/add",Qs.stringify(data))
HTTP.post("basex.log/add",Qs.stringify(data))
.then(r=>{
console.log("submit: ",data);
if(this.checkbox){
@ -2379,7 +2379,7 @@ const Log=Vue.extend({template:`
</v-list>
</v-menu>
</v-toolbar>
<v-data-table :headers="headers" :items="items" :search="search" class="elevation-1" no-data-text="No logs found" v-bind:options.sync="pagination">
<v-data-table :headers="headers" :items="items" :search="search" class="elevation-1" no-data-text="No logs found" sort-by="time" v-bind:options.sync="pagination">
<template slot="items" slot-scope="props">
<td :title="props.item.time">{{ props.item.time }}</td>
<td class="text-xs-right">{{ props.item.user }}</td>
@ -2409,7 +2409,7 @@ const Log=Vue.extend({template:`
{ text: 'address', value: 'address' },
],
items:[],
pagination:{sortBy: 'time',descending:true,rowsPerPage:25},
pagination:{ rowsPerPage:25},
selected:[],
search:"",
loading:false,
@ -5499,7 +5499,7 @@ const Entity=Vue.extend({template:`
<v-text-field prepend-icon="filter_list" label="Filter..." v-model="q" type="search" hide-details single-line @keyup.enter="setfilter" clearable></v-text-field>
<v-spacer></v-spacer>
<v-btn @click="getItems" icon :loading="loading" :disabled="loading"><v-icon>refresh</v-icon></v-btn>
<vp-entitylink entity="entity"></vp-entitylink>
<vp-entitylink entity="dice.entity"></vp-entitylink>
</v-toolbar>
</template>
@ -5639,7 +5639,7 @@ const Entity1=Vue.extend({template:`
</v-layout>
</v-expansion-panel-header>
<v-expansion-panel-content>
<qd-table :headers="headers" :data-uri="&quot;data/entity/&quot;+entity +&quot;/field&quot;" entity="entity.field" no-data-msg="Nothing found">
<qd-table :headers="headers" :data-uri="&quot;data/entity/&quot;+entity +&quot;/field&quot;" entity="dice.field" no-data-msg="Nothing found">
</qd-table>
</v-expansion-panel-content>
</v-expansion-panel>