Last active
May 31, 2018 09:11
-
-
Save lguariento/8129477a4501faf617d28d385e6aeee7 to your computer and use it in GitHub Desktop.
Cardinality error
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>Add a person</title> | |
</head> | |
<body> | |
<div class="templates:surround?with=templates/page.html&at=content"> | |
<div data-template="app:addPers"/> | |
</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
xquery version "3.1"; | |
module namespace app="http://editor.curioustravellers.ac.uk/templates"; | |
import module namespace templates="http://exist-db.org/xquery/templates" ; | |
import module namespace config="http://editor.curioustravellers.ac.uk/config" at "config.xqm"; | |
declare namespace tei="http://www.tei-c.org/ns/1.0"; | |
declare namespace functx = 'http://www.functx.com'; | |
declare option exist:serialize "method=html comedia-type=text/html"; | |
declare function local:get-id($xml-id as xs:string) as xs:integer { | |
xs:integer(replace($xml-id, '[^0-9]+', '')) | |
}; | |
declare function app:listpers($node as node(), $model as map(*)) { | |
for $person in doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person | |
return | |
<tr> | |
<td>{$person/tei:persName/tei:surname}</td> | |
<td>{$person/tei:persName/tei:forename}</td> | |
</tr> | |
}; | |
declare function app:addPers($node as node(), $model as map(*)) { | |
let $peid := doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person[@xml:id][last()]/@xml:id | |
let $idnumber := xs:decimal(substring-after($peid, 'pe')) | |
let $newidnumber := (sum($idnumber + 1)) | |
let $newpeid := concat('pe0', $newidnumber) | |
(: This returns the first available id, even if it's within a gap:) | |
let $id_gap := | |
(for $person in doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person[position() ne last()] | |
where local:get-id($person/@xml:id) ne (local:get-id($person/following-sibling::tei:person[1]/@xml:id) - 1) | |
return (local:get-id($person/@xml:id) + 1))[1] | |
(: This does the same, although it takes way longer to evaluate than the above solution: | |
(for $key in (1 to 9999)!format-number(., '0000') | |
let $pei := concat('pe', $key) | |
where empty(doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person[@xml:id=$pei]) | |
return $key)[1] :) | |
let $idnext := | |
if (empty($id_gap)) then | |
(local:get-id(doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person[last()]/@xml:id) + 1) | |
else ($id_gap) | |
let $newpeid := | |
if (fn:string-length($idnext) = 1) then | |
concat('pe000', $idnext) else if | |
(fn:string-length($idnext) = 2) then | |
concat('pe00', $idnext) else if | |
(fn:string-length($idnext) = 3) then | |
concat('pe0', $idnext) else | |
concat('pe', $idnext) | |
return | |
<div class="container"> | |
<form action="persadded.html" target="persadded" method="POST"> | |
<h1 style="text-align:center;">Add a person</h1> | |
<div class="form-group col-md-3"> | |
<label for="newpeid">ID:</label> | |
<input readonly="readonly" class="form-control" type="text" name="newpeid" value="{$newpeid}"/> | |
<br/> | |
<label for="surname">Surname:</label> | |
<input class="form-control" type="text" name="surname" placeholder="surname"/> | |
<br/> | |
<label for="forename">Forename:</label> | |
<input class="form-control" type="text" name="forename" placeholder="forename"/> | |
<br/> | |
</div> | |
<div class="col-md-9"> | |
<br/> | |
<iframe scrolling="no" style="border: none; width:100%; height: 350px;" name="persadded"></iframe> | |
</div> | |
<br/> | |
<input class="btn btn-primary btn-lg" id="submit" type="submit" value="Submit"/> | |
</div> | |
<br/> | |
</form> | |
</div> | |
}; | |
declare function app:persadded($node as node(), $model as map(*)) { | |
let $newpeid := request:get-parameter('newpeid', '') | |
let $surname := request:get-parameter('surname', '') | |
let $forename := request:get-parameter('forename', '') | |
let $on-disk := doc('/db/apps/app-ct/data/indices/pedb.xml') | |
let $newrecord := | |
<person xmlns="http://www.tei-c.org/ns/1.0" xml:id="{xs:ID($newpeid)}" > | |
<persName> | |
<surname>{$surname}</surname> | |
<forename>{$forename}</forename> | |
</persName> | |
</person> | |
let $previous := local:get-id($newpeid) - 1 | |
let $previd := | |
if (fn:string-length($previous) = 1) then | |
concat('pe000', $previous) else if | |
(fn:string-length($previous) = 2) then | |
concat('pe00', $previous) else if | |
(fn:string-length($previous) = 3) then | |
concat('pe0', $previous) else | |
concat('pe', $previous) | |
let $insert := update insert $newrecord following $on-disk//tei:person[@xml:id eq $previd] | |
return | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>Added {$newpeid}</title> | |
</head> | |
<body> | |
<div style="background:floralwhite; text-align:center; border-radius: 80px; overflow: hidden;"> | |
<br /> | |
<h3>You have just added {($surname, $forename)} to the database</h3> | |
</div> | |
</body> | |
</html> | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?><?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" | |
schematypens="http://purl.oclc.org/dsdl/schematron"?> | |
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="pldb"> | |
<teiHeader> | |
<fileDesc> | |
<titleStmt> | |
<title>Database of places</title> | |
</titleStmt> | |
<publicationStmt> | |
<ab/> | |
</publicationStmt> | |
<sourceDesc> | |
<ab/> | |
</sourceDesc> | |
</fileDesc> | |
</teiHeader> | |
<text> | |
<body> | |
<listPerson> | |
<person xml:id="pe0001"> | |
<persName> | |
<surname>Person</surname> | |
<forename>One</forename> | |
</persName> | |
</person> | |
<person xml:id="pe0007"> | |
<persName> | |
<surname>Person 2</surname> | |
<forename/> | |
</persName> | |
</person> | |
<person xml:id="pe0009"> | |
<persName> | |
<surname>Person</surname> | |
<forename>Three</forename> | |
</persName> | |
</person> | |
<person xml:id="pe0011"> | |
<persName> | |
<surname>Person</surname> | |
<forename>Four</forename> | |
</persName> | |
</person> | |
</listPerson> | |
</body> | |
</text> | |
</TEI> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>Person added</title> | |
</head> | |
<body> | |
<div data-template="app:persadded"/> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>Persons list</title> | |
</head> | |
<body id="body"> | |
<div class="templates:surround?with=templates/page.html&at=content"> | |
<h1 style="text-align:center;">Persons list</h1> | |
<p> | |
<br/> | |
<br/> | |
<a style="font-size: 18px;" class="btn btn-primary btn-block" href="addnewperson.html"> | |
<span aria-hidden="true"/> Add a new person | |
</a> | |
</p> | |
<table id="persons" class="display table table-hover table-bordered"> | |
<thead> | |
<tr> | |
<th class="col-md-1">ID<br/> | |
</th> | |
<th class="col-md-11">Surname<br/> | |
</th> | |
</tr> | |
</thead> | |
<tbody data-template="app:listpers"/> | |
</table> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The persons.html page shows a table with all the persons in the pedb.xml.
The addnewpersons.html calls the app:addPers, which iterates in the xml:ids in pedb.xml and, if it finds a 'gap', returns the first available xml:id (in this case pe0002). Once the form is filled and submitted, a new record is created (e.g. pe0002). Now, if we go to persons.html we don't see the new person added, even if it is actually in the pedb.xml file. One needs to force a refresh of the page, or append a cache-busting parameter to the address (e.g. persons.html?rand=345345345). Then the new person is shown.
Moreover, if we go to addnewperson.html again immediately after pe0002 has been added, one gets this error (line 855 is where
where local:get-id($person/@xml:id) ne (local:get-id($person/following-sibling::tei:person[1]/@xml:id) - 1)
is):If the
$id_gap
code is commented in the app.xql and we just use$idnext := (local:get-id(doc('/db/apps/app-ct/data/indices/pedb.xml')//tei:listPerson/tei:person[last()]/@xml:id) + 1)
, i.e. if we just use the next to the last available xml:id, then the cardinality error disappears. The issue with the newly added record not shown in persons.html unless cache-busting triks are used still remains, though.