13. Key-value store

13.1. Abstract

Key Value Store (KVS) is een software met als oorspronkelijk intentie op een gemakkelijke manier invulvelden aan een bestaande applicatie te kunnen toevoegen. Gaandeweg werd ze verfijnd en uitgebreid en gebruikt om volledig nieuwe applicaties op te bouwen.

De naam verwijst naar het filing-mechanisme: een subscript en een waarde, zonder verdere onderverdelingen.

13.2. Algemeen principe

Attributen vormen de kern van KVS. Zij komen overeen met de keys die in de databank gefiled worden met een bepaalde waarde. Attributen worden gegroepeerd in attributensets. De volledige identificatie van een attribuut is dan ook: attribuutset:attribuut.

Een omgeving is een verzameling van attributen die, binnen een bepaalde applicatie, bij mekaar horen. Deze attributen kunnen uit verschillende attributensets afkomstig zijn.

Een applicatie kan 1 of meerdere omgevingen bevatten of eruit opgebouwd zijn en moet de KVS macro’s aanspreken om de gegevens op te laden, te formateren, te transformeren, te testen en te bewaren.

13.3. Attributensets

Attributensets zijn verzamelingen van attributen en komen met hun eigen meta-informatie.

Aan een attributenset is altijd een namespace verbonden waarin de taalafhankelijke verwoordingen van de attributenset geplaatst worden onder titleset*attributensetidentifier*.

Een attributenset kan een alias hebben, d.i. een andere attributenset. In dat geval is het een zgn. virtuele set waarvan de attributen bij de alias moeten gezocht worden maar die wel een eigen namespace heeft waarin eventueel alternatieve verwoordingen voor de attributen staan.

13.4. Attributen

Attributen vormen de kern van KVS. Zij komen overeen met de identificatie van een op te slagen waarde.

De verwoordingen van een attribuut, en bijhorende infovelden, worden niet in de meta-info van het attribuut zelf opgeslagen, maar komen terecht in de namespace van de bijhorende attributenset. Indien het een virtuele attributenset betreft kan zo’n verwoording de placeholder $alias bevatten. Dit wordt dan vervangen door de verwoording van het attribuut in de alias-set.

De taalafhankelijke scope-velden worden getoond door de optie Informatie van het contextmenu.

13.4.1. Algemene eigenschappen rond vormgeving

13.4.1.1. Standaardwaarde - default

De allereerste keer dat het attribuut getoond wordt, in een nieuw record van de applicatie dus, wordt het met de hier ingevulde waarde gepresenteerd. Zodra er effectief een waarde is toegekend aan het attribuut wordt deze nooit door de standaardwaarde overschreven.

13.4.1.2. Eenheid - unit

Een zuiver visuele eigenschap die de hier ingevulde eenheid achter het invulveld in de interface plaatst.

13.4.1.3. Afmeting invulveld - size

De gewenste afmeting van het invulveld, uitgedrukt in ex. Voor textarea’s kan breedte x hoogte ingevuld worden.

13.4.1.4. Toon altijd in deze mode - mode

De mode (edit of view) wordt bepaald door de parameter $mode van de macro m4_formatKeyValueStore. Default is dit edit. Een attribuut dat aan de macro is meegegeven, wordt dan in die mode getoond, tenzij in deze eigenschap expliciet is aangegeven dat het altijd in bvb. view-mode moet getoond worden.

Dit kan mogelijk nog overruled worden door de eigenschap Enkel editeerbaar voor, en Altijd verborgen voor.

13.4.1.5. Enkel editeerbaar voor - accedit

Indien niets ingevuld, kan iedereen die de applicatie kan opstarten die het attribuut gebruikt, het attribuut ook editeren (tenzij anders gespecificeerd door de eigenschap Toon altijd in deze mode).

Indien toegangssloten ingevuld, is het attribuut enkel editeerbaar voor gebruikers die aan minstens 1 toegangsslot voldoen.

13.4.1.6. Altijd bekijk-mode voor - accview

Indien toegangssloten ingevuld, verschijnt het attribuut altijd in view-mode voor gebruikers die aan minstens 1 toegangsslot voldoen.

13.4.1.7. Altijd verborgen voor - acchidden

Indien toegangssloten ingevuld, is het attribuut nooit zichtbaar voor gebruikers die aan minstens 1 toegangsslot voldoen.

13.4.1.8. Berekening extra informatie - extraexec

M-exe voor de berekening van een extra informatie blok dat boven het invulveld geplaatst wordt. De executable moet de parameters leveren voor de extrainfotemplate in RAkvsinf en krijgt de waarde van het attribuut ter beschikking in RDkvsinf.

De executable kan beschikken over volgende array:

  • RAkvsval("key")=key waarbij key de naam van het te tekenen attribuut is
  • RAkvsval("index")=n waarbij n het volgnummer van key is indien repetitief. Altijd 1 indien niet repetitief of deel van een groep.
  • RAkvsval("groupindex")=ng waarbij ng het volgnummer van de groep is waarvan key deel uitmaakt. Indien key geen deel is van een groep is ng=0.
  • RAkvsval("values",*,*n)=val waarbij * alle attributen zijn in de huidige content, *n alle volgnummers van de attributen zijn indien repetitief, anders altijd 1, val de waarde is van volgnummer n van het attribuut

13.4.1.9. Template extra informatie - extratemplate

Template die gevoed wordt door RAkvsinf, berekend in extraexec, en het blok met extra informatie tekent.

13.4.1.10. Identifier - id

Een identifier die bij het tekenen van het element in html-attribuut data-kvsid terecht komt.

13.4.2. Templates

Elk attribuut heeft een default template die eigen is aan z’n natuur.

De default template kan overruled worden door een specifieke, ingevulde of berekende, template. Daarbij heeft een ingevulde template voorrang op een berekende template.

Templates mogen taalcodes en tekstfragmenten hebben als placeholders, en moeten $_*attribuut* bevatten, of, in het geval van een groep, $_*attribuut* van elke deelattribuut. Staan er nog andere placeholders in, dan moeten deze berekend worden via Berekening extra placeholders.

13.4.2.1. Berekening opbouw template - exec

Een attribuut wordt getoond via een default template, of via een in de meta-informatie ingevulde template, of via het uitvoeren van deze executable (x executable). De executable moet rekening houden met RDmode (edit|view|presentation) en het resultaat teruggeven in RDformat.

De executable kan beschikken over volgende array:

  • RAkvsval("key")=key waarbij key de naam van het te tekenen attribuut is
  • RAkvsval("index")=n waarbij n het volgnummer van key is indien repetitief. Altijd 1 indien niet repetitief of deel van een groep.
  • RAkvsval("groupindex")=ng waarbij ng het volgnummer van de groep is waarvan key deel uitmaakt. Indien key geen deel is van een groep is ng=0.
  • RAkvsval("values",*,*n)=val waarbij * alle attributen zijn in de huidige content, *n alle volgnummers van de attributen zijn indien repetitief, anders altijd 1, val de waarde is van volgnummer n van het attribuut

13.4.2.2. Berekening extra placeholders - execpar

Indien de gebruikte template andere placeholders bevat dan tekstfragmenten, taalcodes en $*attribuut*, moeten deze via de hier ingevulde executable berekend worden en terechtkomen in RAkeyref.

De executable kan beschikken over volgende array:

  • RAkvsval("key")=key waarbij key de naam van het te tekenen attribuut is
  • RAkvsval("index")=n waarbij n het volgnummer van key is indien repetitief. Altijd 1 indien niet repetitief of deel van een groep.
  • RAkvsval("groupindex")=ng waarbij ng het volgnummer van de groep is waarvan key deel uitmaakt. Indien key geen deel is van een groep is ng=0.
  • RAkvsval("values",*,*n)=val waarbij * alle attributen zijn in de huidige content, *n alle volgnummers van de attributen zijn indien repetitief, anders altijd 1, val de waarde is van volgnummer n van het attribuut

13.4.2.3. Template edit mode - etemplate

Indien ingevuld overrulet dit de default template in edit-mode.

13.4.2.4. Template view mode - vtemplate

Indien ingevuld overrulet dit de default template in view-mode.

13.4.2.5. Template presentatie mode- ptemplate

Indien ingevuld overrulet dit de default template in presentatie-mode. Deze mode is bedoeld voor gebruik van het attribuut in een zuivere presentatie-context, vb. een OPAC.

Er kunnen meerdere presentatie-templates ingevuld worden, elk met hun eigen identificatie. Deze identificatie kan meegegeven worden aan de $mode parameter van de macro m4_formatKeyValueStore.

13.4.3. Verwerking

13.4.3.1. Sleutel - key

Indien het attribuut als sleutel is aangevinkt, moeten alle waarden van het attribuut die in het invulformulier voorkomen, uniek zijn.

13.4.3.2. Transformatie expressie - trans

I.p.v. de default transformatie, die afhangt van de natuur van het attribuut, kan hier een specifieke transformatie opgegeven worden (x trans). Deze kan werken met RDkvk, de naam van het attribuut, en met RDkvv, de waarde van het attribuut. De getransformeerde waarde moet terug in RDkvv geplaatst worden.

13.4.3.3. Test expressie - test

I.p.v. de default test, die afhangt van de natuur van het attribuut, kan hier een specifieke test opgegeven worden (x test). Deze kan werken met RDkvk, de naam van het attribuut, en met RDkvv, de waarde van het attribuut. Indien het attribuut multiple is, is de numerieke array RAkvv beschikbaar, met alle waarden van het attribuut. Een eventuele fout moet geplaatst worden in RDerror, een waarschuwing in RDwarn, beide in de vorm taalcode^extra info.

13.4.3.4. Altijd testen - testalways

Indien niet aangevinkt wordt de waarde enkel getest indien het veld in het formulier gefocust, en dus mogelijk veranderd werd.

13.4.3.5. Niet versleepbaar - notdraggable

Indien aangevinkt, kan dit attribuut niet versleept worden. Indien een groep ‘niet versleepbaar’ is, zijn alle deelattributen ook ‘niet versleepbaar’. Niet versleepbare attributen krijgen in het ontvangende formulier de css-klasse kvs_drop_missing toegekend. Er wordt tevens een waarschuwing getoond bij versleping van de omhullende omgeving.

13.4.4. Natuur van het attribuut

Een attribuut heeft altijd een bepaalde natuur, waar dan weer specifieke eigenschappen aan gekoppeld zijn. De verschillende natuurtypes zijn zeer ‘basic’ gehouden, er van uitgaand dat ‘hogere’ types (vb. persoonsnaam) altijd vanuit de basic types kunnen samengesteld worden.

In de toekomst kan dit veranderen en worden mogelijk toch een aantal ‘hogere’ natuurtypes toegevoegd.

13.4.4.1. groep - group

Een groep is een aggregatie van verschillende niet-groep attributen, die elk maar 1 keer kunnen voorkomen. In de interface worden ze als een logisch samenhangend geheel gepresenteerd.

Samenstellende attributen (group):
 opsomming van de attributen, in numerieke volgorde, die deel uitmaken van de groep
Attributen voor sleutel (gkey):
 opsomming van de attributen, gescheiden door ;, die samen de sleutel van de groep vormen. Indien de groep meerdere keren voorkomt in een formulier, moeten de gecombineerde sleutelwaarden uniek zijn.
Attributen voor ‘leeg’ (gempty):
 opsomming van de attributen, gescheiden door ;, die, als ze allemaal leeg zijn, de groep als leeg definiëren

13.4.4.2. booleaanse waarde - bool

Een dergelijk attribuut kan slechts 2 mogelijke waarden hebben, 1 of 0, en wordt in de interface voorgesteld als een checkbox. De verwoordingen van true en false (voor view-mode) moeten geplaatst worden in de namespace die verbonden is aan de attribuutset, onder de tekstfragmenten *attribuut*true en *attribuut*false.

13.4.4.3. geheel getal - integer

In de interface wordt deze natuur voorgesteld als een invulveld. De default transformatie herleidt altijd naar een geheel getal, de default testen checken op geldigheid en op de minimum en maximum waarden.

Minimum waarde (imin):
 laagst toegelaten waarde
Maximum waarde (imax):
 hoogst toegelaten waarde
Skip karakter (iskip):
 de gebruiker kan de minimum en maximum waarden overrulen door het hier opgegeven karakter mee in te voeren

13.4.4.4. decimaal getal - float

In de interface wordt deze natuur voorgesteld als een invulveld. De default transformatie herleidt naar een decimaal getal, de default testen checken op geldigheid en op de minimum en maximum waarden.

Minimum waarde (fmin):
 laagst toegelaten waarde
Maximum waarde (fmax):
 hoogst toegelaten waarde
Skip karakter (fskip):
 de gebruiker kan de minimum en maximum waarden overrulen door het hier opgegeven karakter mee in te voeren

13.4.4.5. enkele keuze- choice

Keuze van 1 waarde uit een reeks voorgestelde waarden.

Opties (optionc):
 keuzemogelijkheden in sequentiële volgorde. Een optie heeft de vorm waarde:tekstcode voor verwoording. Indien geen tekstcode wordt gegeven, geldt de waarde als tekstcode. Indien de tekstcode geen namespace bevat wordt de namespace van de attribuutset gebruikt. Indien de tekstcode niet bestaat, wordt de waarde as is genomen.
Bereken de opties (optexec):
 M-expressie die toelaat de keuzemogelijkheden te berekenen in real time. De expressie krijgt RDkvk met de naam van het attribuut ter beschikking en moet de opties teruggeven in RAkvkopt in sequentiële volgorde. De waarde van RAkvkopt kan een getal uit de sequentie zijn. In dat geval wordt de overeenkomende optie de geselecteerde optie in de weergave.
Stel voor als (elementc):
 keuze tussen een selectbox en radio buttons

13.4.4.6. meerdere keuzes - multi

Keuze van meerdere waarden uit een reeks voorgestelde waarden.

Stel voor als (elementm):
 keuze tussen checkboxen, een textinput veld of een textarea. In het eerste geval zijn de keuzemogelijkheden vastgelegd in Opties, in de 2 andere gevallen is er een geassocieerd lookup object van waaruit gekozen kan worden.
Opties (optionm):
 keuzemogelijkheden in sequentiële volgorde in geval van checkboxen. Een optie heeft de vorm waarde:tekstcode voor verwoording. Indien geen tekstcode wordt gegeven, geldt de waarde als tekstcode. Indien de tekstcode geen namespace bevat wordt de namespace van de attribuutset gebruikt.
Bereken de opties (optexem):
 M-expressie die toelaat de keuzemogelijkheden te berekenen in real time. De expressie krijgt RDkvk met de naam van het attribuut ter beschikking en moet de opties teruggeven in RAkvkopt in sequentiële volgorde. De waarde van RAkvkopt kan een getal uit de sequentie zijn. In dat geval wordt de overeenkomende optie de geselecteerde optie in de weergave.
Geassocieerd lookup object (lookupm):
 in geval van textinput of textarea

13.4.4.7. karakterrij - string

Patroon (pattern):
 een M of Python glob patroon waaraan de string moet voldoen
Stel voor als (elements):
 textinput of textarea
Geassocieerd lookup object (lookups):
 niet verplicht
Markdown toegelaten (smarkdown):
 aan te vinken indien de string in markdown formaat moet kunnen ingevoerd worden
Upload (upload):
 aan te vinken indien naast het invulveld een uploadelement moet geplaatst worden. De opgeladen file komt in docman terecht (gedurende 21 dagen) en het docman-path wordt de waarde van het invulveld. Om dit te activeren moet m4_documentElementFormStart(upload=1) in de applicatie gezet worden.

13.4.4.8. datum - date

Een invulveld dat geassocieerd is met de datepicker widget. Om die te activeren moeten een aantal m4’s in de header van de applicatie gezet worden. Zie Invoeren en tonen van datum in Brocade.

Vroegste datum (dmin):
 minimum in te voeren datum
Laatste datum (dmax):
 maximum in te voeren datum
Skip karakter (dskip):
 de gebruiker kan de minimum en maximum datums overrulen door het hier opgegeven karakter mee in te voeren
Type (dtype):default, from, until of multi. Zie Invoeren en tonen van datum in Brocade (dptype).

13.4.4.9. loi - loi

Een invulveld waarin enkel LOI’s kunnen ingevoerd worden.

Type loi (ltype):
 het soort LOI dat kan ingegeven worden
Geassocieerd lookup object (lookupl):
 het met deze loi geassocieerde lookup object

13.4.4.10. tabel - table

Een tabel waarvan de cellen bestaan uit invulvelden of checkboxen.

Layout cellen (cell):
 bevatten de cellen een textinput veld of een checkbox
Bereken tabel (texe):
 een M-executable die RAkeytab oplevert. Deze array bevat de rij- en kolomspecificaties, zijnde de hoofding in subscript title en de identificatie in subscript id.
s RAkeytab("row",1,"title")="rij1"
s RAkeytab("row",2,"title")="rij2"
s RAkeytab("row",3,"title")="rij3"
s RAkeytab("col",1,"title")="kol1"
s RAkeytab("col",2,"title")="kol2"
s RAkeytab("col",3,"title")="kol3"
s RAkeytab("col",4,"title")="kol4"
s RAkeytab("row",1,"id")="ra"
s RAkeytab("row",2,"id")="rb"
s RAkeytab("row",3,"id")="rc"
s RAkeytab("col",1,"id")="ca"
s RAkeytab("col",2,"id")="cb"
s RAkeytab("col",3,"id")="cc"
s RAkeytab("col",4,"id")="cd"

Bovenstaand voorbeeld levert een tabel op met 3 rijen en 4 kolommen. De cellen worden gespecificeerd als ra-ca, ra-cb, ra-cc, ....

Een tabel kan onderdeel zijn van een groep.

13.4.4.11. label - label

Een attribuut met natuur label wordt altijd in view-mode getoond. Er moet altijd een template voorzien zijn, hetzij ingevuld in ‘Template edit of view mode’, hetzij berekend.

13.5. Omgevingen

Een omgeving (content) is een begrip dat bij een bepaalde applicatie hoort en voor deze applicatie logisch bij elkaar horende attributen groepeert. In de interface wordt een omgeving als een HTML fieldset voorgesteld.

13.5.1. Eigenschappen

Taalafhankelijke verwoordingen:
 

deze worden opgeslagen in de geassocieerde namespace onder title*omgevingsidentifier*

Namespace:

geassocieerde namespace waarin momenteel enkel de verwoording van de omgeving terecht komt

Default attributenset:
 

indien attributen van de omgeving zonder set opgegeven zijn, wordt de default set eraan toegevoegd (in macro’s, bij opslag enz.)

Attributen:

Opsomming van de attributen die tot deze omgeving behoren. Aan attributen zonder set-specificatie wordt de default attributenset geplakt. Elk attribuut kan aangevuld zijn met:

  • * = attribuut is repetitief met herhaalde invulvelden
  • # = repetitief in textarea (enkel voor naturetypes die d.m.v. een inputtext veld ingevuld worden)
  • ; = repetitief in textinput, gescheiden door ; (enkel voor natuurtypes die d.m.v. een inputtext veld ingevuld worden)
  • ! = waarde verplicht, dus dit attribuut moet ingevuld worden
Global:

KVS moet, per applicatie, weten waar de gegevens moeten opgeslagen worden. Dit kan expliciet aan de macro meegegeven worden of hier opgepikt worden. Subscripts s*nummer* worden vervangen door $p($sub,":",n) waarbij $sub een parameter is die meegegeven wordt met macro m4_fileKeyValueStore.

Global voor logging:
 

Global waar informatie over veranderde records moet weggeschreven worden. Indien niets ingevuld gebeurt er geen logging voor deze omgeving.

Algemene testprocedure:
 

M-expressie, testprocedure voor de volledige omgeving. Krijgt RAkvsval(attrname,n) ter beschikking met de waarden van alle attributen en moet zelf m4_setError zetten indien nodig. Deze test wordt als eerste uitgevoerd, dus voor de tests op de afzonderlijke attributen.

Toon dropzone:

Indien aangevinkt wordt, in HTML5-compatibele browsers, een icoon zichtbaar waarnaar een csv-file kan gesleept worden om de attribuutvelden in 1 beweging te overschrijven.

Andere omgevingen in dropzone:
 

Van een csv-file die naar een dropzone gesleept wordt, worden in principe enkel de attributen van de omgeving in kwestie overgenomen. Als deze optie is aangevinkt, worden ook andere omgevingen ingevuld die in de csv-file ingevuld zijn

Draggable:

Indien aangevinkt, genereert, in HTML5-compatibele browsers, versleping van het omgevingslabel een csv-structuur die ergens kan gedropt worden, bvb. in een dropzone van een andere omgeving.

Encoding csv-file:
 

encoding van de gedropte csv-file (default latin1)

Dupliceren via context-menu:
 

Het dupliceren van attributen gebeurt default via een dupliceerknop. Indien deze optie is aangevinkt verdwijnt de knop en verschijnt de actie Dupliceer in het contextmenu.

Display:

de initiële displaymode van de omgeving: block of none

Voorwaarde voor tonen:
 

dit is een M-expressie die RDcntShw op 0 moet zetten indien deze omgeving onder bepaalde omstandigheden niet moet getoond worden.

13.6. Bewerkingen

De macro’s voor laden, formateren, transformeren, testen en bewaren van KVS gegevens, kunnen op 3 verschillende manieren aangesproken worden:

  • met expliciete vermelding van 1 attribuut in parameter $att
  • met invulling van een identifier, verkregen via m4_initKeyValueStore, in parameter $id. Dan worden alle attributen behandeld die via $id geinitialiseerd zijn
  • met invulling van een omgeving in $content. Dan worden alle attributen behandeld die bij die omgeving horen.

Aan alle macro’s kan een array meegegeven worden met de te bewerken gegevens. Gebeurt dit niet, dan probeert de software de te bewerken gegevens op te halen uit de interne array CAkvsset die automatisch opgebouwd wordt uit de gegevens van het invulformulier. Hiervoor is het wel noodzakelijk dat opeenvolgende macro’s op dezelfde manier aangesproken worden, bvb. een load met een attribuut en load met een omgeving, dan ook een format met een attribuut en een format met een omgeving, evenals een trans met dat attribuut en een trans met die omgeving.

13.6.1. Macro’s

13.6.1.1. Initialiseren

Dit is enkel nuttig indien om 1 of andere reden enkele, maar niet alle, attributen van een omgeving dienen bewerkt te worden. De macro geeft een identifier $id terug die aan de andere bewerkingsmacro’s kan doorgespeeld worden.

macro initKeyValueStore($id,$att="",$content):
    '''
    $synopsis: Initialiseer een kvs bewerking. Dit houdt in het kenbaar maken van de te bewerken
               attributen.
    $id: resultaat: identifier van de initialisatie
    $att: Array met numerieke subscripts en attributen als waarde
          Elk attribuut kan aangevuld zijn met
                "*" = repetitief met herhaalde invulvelden
             of "#" = repetitief in textarea (enkel voor natures die textinput hebben)
             of ";" = repetitief in textinput (enkel voor natures die textinput hebben)
          en/of "!" = waarde verplicht
          Indien leeg worden alle attributen die in de meta-info van $content gedefinieerd zijn
          in $att geplaatst
    $content: content id.
              OPGELET, alle te initialiseren attributen moeten tot dezelfde content behoren!
    $example: m4_initKeyValueStore(id,att)
    '''
    «s $id=$$%Init^bkvsexec(.$att,$content)»
Voorbeeld:initialiseer 5 attributen. De identifier komt in FDid1.
def Init:
 n RAtt
 s RAtt(1)="seteen:testfloat*!"
 s RAtt(2)="seteen:testinteger*"
 s RAtt(3)="settwee:testchoice*"
 s RAtt(4)="settwee:testmulti!*"
 s RAtt(5)="settwee:testlabel"
 m4_initKeyValueStore(FDid1,RAtt,"testeen")

13.6.1.2. Laden

Attributen worden altijd opgehaald in volledige notatie set:attribuut, ook al zijn ze gecomprimeerd, d.i. zonder set, weggeschreven.

macro loadKeyValueStore($value,$global="",$att="",$content="",$id="",$sub="",$defset=1):
    '''
    $synopsis: Haal de waarde(n) op van een attribuut,
               of een reeks attributen geinitialiseerd met m4_initKeyValueStore
               Kan enkel gebruikt worden indien @$global@("kvs") bestaat.
    $value: array met content in eerste en attribuut in tweede subscript,
            volgende numerieke subscripts met waarde in rechterlid
    $global: de globaltak waar de attributen moeten gezocht worden.
             vb. ^BCAT("lvd",12345)
             Indien niet ingevuld wordt gekeken bij de meta-info van de omgeving
    $att: het op te halen attribuut (set:attribuut).
          Indien niet ingevuld moet in principe $id ingevuld zijn.
          Indien ook $id niet ingevuld is moet $content ingevuld zijn en worden alle attributen
          in $global van $content opgehaald. Opgelet hierbij, lege attributen werden immers
          niet gefiled!
    $content: content id voor op te halen attribuut
              Indien leeg moet $id ingevuld zijn
    $id: de initiatie identifier die eventueel moet overlopen worden (zie m4_initKeyValueStore)
         Indien leeg moet in principe $att en $content ingevuld zijn.
         Indien enkel $content is ingevuld worden alle attributen in $global van $content
         opgehaald.
         Opgelet hierbij, lege attributen werden immers niet gefiled!
    $sub: enkel van toepassing indien $global="". Bevat 'identifier', onderverdeeld met ':'
          (vb. loi) waarvan de delen overeenkomen met s1,s2,... in de globaldefinitie
          van de meta-info van de content, s0 met de volledige 'identifier'
    $defset: 1 = de attributen werden weggeschreven zonder set indien hun set = de default set
             van de content
    $example: m4_loadKeyValueStore(RAvalue,global,att,content)
    '''
    «d %Load^bkvsexec(.$value,$global,$att,$content,.$id,$sub,$defset)»
Voorbeeld 1:laad attributen geinitialiseerd met FDid1.
def Load:
 m4_loadKeyValueStore(RAvalue,id=FDid1,sub="een:twee:drie")
Voorbeeld 2:laad 2 specifieke attributen. Initialisatie is dan niet nodig.
def Load:
 m4_loadKeyValueStore(RAvalue,att="seteen:testbool",content="testeen",sub="een:twee:drie")
 m4_loadKeyValueStore(RAvalue,att="settwee:teststring",content="testtwee",sub="een:twee:drie")
Voorbeeld 3:laad de bij content testdrie gespecificeerde attributen. Initialisatie is dan niet nodig.
def Load:
 m4_loadKeyValueStore(RAvalue,content="testdrie",sub="een:twee:drie")

13.6.1.3. Normalizeren

Deze macro transformeert opgehaalde gegevens naar een meer ‘natuurlijke’ vorm.

macro normalizeKeyValueStore($normal,$value,$content,$attr="",$defset=1):
    '''
    $synopsis: 'Normaliseer' de met m4_loadKeyValueStore opgehaalde waarden van een bepaalde
               omgeving
                - geen groep, single value, geen key  : $normal(att)=value
                - geen groep, single value, key       : $normal(att,value)=""
                - multi altijd behandelen als key     : $normal(att,value)=n
                  met volgorde in waarde
                - geen groep, multiple value, geen key: $normal(att,n)=value
                - geen groep, multiple value, key     : $normal(att,n,value)=""
                - groep, single value, geen keys      : $normal(att,nkey1)=value_nkey1
                - groep, single value, keys           : $normal(att,value_key1,
                                                        value_key2,..,nkey1)=value_nkey1
                - groep, multiple values, geen keys   : $normal(att,n,nkey1)=value_nkey1
                - groep, multiple values, keys        : $normal(att,n,value_key1,
                                                        value_key2,..,nkey1)=value_nkey1
    $normal: de genormalizeerde array
    $value: een array zoals aangemaakt door m4_loadKeyValueStore
    $content: content id
    $attr: attribuut
    $defset: 1 = het eerste subscript van $normal is het attribuut zonder set
                 indien de set gelijk is aan de default set van de content
    $example: m4_normalizeKeyValueStore(RAnormal,RAvalue,content)
    '''
    «d %Normal^bkvsexec(.$normal,.$value,$content,$attr,$defset)»
Voorbeeld:omgeving testdrie bevat attributen settwee:testbool, settwee:testdate, settwee:testgroup, settwee:testinteger en settwee:testloi. settwee:testgroup is een groep waarin settwee:testfloat en settwee:testchoice sleutelelementen zijn.
GT.M>m4_loadKeyValueStore(.RAl,content="testdrie",sub="een:twee:drie")

GT.M>zwr RAl
RAl("testdrie","settwee:testbool",1)=0
RAl("testdrie","settwee:testdate",1)="62659,"
RAl("testdrie","settwee:testgroup",1)=$C(4,1)_"0"_$C(1,20,1)_"settwee:testbool"_
$C(1)_"1"_$C(27,1)_"settwee:testchoice"_$C(1)_"keuze3"_$C(22,1)_"settwee:testfloat"_
$C(1)_"75"_$C(26,1)_"settwee:testmulti"_$C(1)_"multi3"_$C(21,1)_"settwee:teststring"_$C(1)
RAl("testdrie","settwee:testinteger",1)=""
RAl("testdrie","settwee:testloi",1)=""

GT.M>m4_normalizeKeyValueStore(RAn,RAl,content="testdrie")

GT.M>zwr RAn
RAn("testbool")=0
RAn("testdate")="62659,"
RAn("testgroup",75,"keuze3","testbool")=1
RAn("testgroup",75,"keuze3","testmulti","multi3")=1
RAn("testgroup",75,"keuze3","teststring")=""
RAn("testinteger",1)=""
RAn("testloi",1)=""

13.6.1.4. Denormalizeren

Het tegenovergestelde van normalizeren, dus van de ‘natuurlijke’ vorm naar de vorm zoals gemaakt door macro m4_loadKeyValueStore.

macro denormalizeKeyValueStore($value,$normal,$content,$attr=""):
 '''
 $synopsis: 'Denormaliseer' een array naar een array zoals opgehaald door m4_loadKeyValueStore
 $value: resultaat: een array zoals aangemaakt door m4_loadKeyValueStore
 $normal: de genormalizeerde array
 $content: content id
 $attr: attribuut
 $example: m4_denormalizeKeyValueStore(RAvalue,RAnormal,content)
 '''
 «d %Dnormal^bkvsexec(.$value,.$normal,$content,$attr)»

13.6.1.5. Formateren

De attributen worden getekend in volgorde van aanspreking door m4_formatKeyValueStore. De software detecteert automatisch begin en einde van omgevingen en tekent daarvoor ook de nodige elementen.

macro formatKeyValueStore($att="",$content="",$value="",$mode="edit",$default=1,
                          $repeat=0,$id="",$access=""):
'''
$synopsis: Teken een attribuut,
           of een reeks attributen geinitialiseerd met m4_initKeyValueStore
$att: het te formateren attribuut (set:attribuut). Indien niet ingevuld moet
      $id ingevuld zijn
$content: content id van te formateren attribuut
          Indien leeg moet $id ingevuld zijn
$value: array met content in eerste en attribuut in tweede subscript,
        volgende numerieke subscripts met waarde in rechterlid.
        Indien niet ingevuld wordt gekeken of er waarden in
        CAkvsset($id,$content,$att,n) staan.
        Structuur zoals opgebouwd door m4_transKeyValueStore
$mode: edit | view | presentation | ptemplate-identifier
$default: forceer default template bij $mode, ook al is in de meta-info
          een specifieke template ingevuld
$repeat: * = repetitief met herhaalde invulvelden
         # = repetitief in textarea (enkel voor natures die textinput hebben)
         ; = repetitief in textinput (enkel voor natures die textinput hebben)
         0 = niet repetitief
         Geen betekenis indien $mode'="edit" of indien $id ingevuld is.
         In het laatste geval wordt daar gekeken naar "*", "#", of ";" modifier.
         Indien enkel $content is ingevuld kan $repeat eventueel gebruikt worden om de bij de
         omgeving ingevulde herhaalbaarheid te overrulen.
$id: de initiatie identifier die eventueel moet overlopen worden (zie m4_initKeyValueStore)
     Indien leeg moet $att en $content ingevuld zijn,
     ofwel enkel $content en dan worden alle in de meta-info van $content gespecificeerde
     attributen geformateerd
$access: overrulet toegangssloten in meta-informatie van behandelde attribu(u)t(en)
         array met volgende mogelijke subscripts:
         edit: enkel editeerbaar voor opgesomde toegangssloten (delimiter=;)
         view: altijd bekijk-mode voor opgesomde toegangssloten
         hidden: altijd hidden voor opgesomde toegangssloten
$example: m4_formatKeyValueStore(att,content,RAvalue)
          m4_formatKeyValueStore(id)
'''
«d %Loop^bkvsexec(.$value,$att,$content,$id,"",$repeat,$mode,$default,.$access,"form")»
Voorbeeld 1:toon attributen geinitialiseerd met FDid1.
def Format:
 m4_formatKeyValueStore(RAvalue,id=FDid1,sub="een:twee:drie")
Voorbeeld 2:toon 2 specifieke attributen.
def Format:
 n content,att
 s content="testeen"
 s att="seteen:testbool"
 m4_formatKeyValueStore(att,content,RAvalue,mode=FDmode,default=FDdef)
 s content="testtwee"
 s att="settwee:teststring"
 m4_formatKeyValueStore(att,content,RAvalue,repeat="*",mode=FDmode,default=FDdef)
Voorbeeld 3:toon de bij content testdrie gespecificeerde attributen.
def Format:
 m4_formatKeyValueStore(content="testdrie",default=FDdef)

13.6.1.6. Transformeren

De transformatie kan expliciet door de applicatie uitgevoerd worden. Zoniet, probeert m4_formatKeyValueStore automatisch de nodige transformaties te doen.
macro transKeyValueStore($value,$att="",$content="",$id=""):
 '''
 $synopsis: Transformeer de waarde(n) van een attribuut,
             of een reeks attributen, geinitialiseerd met m4_initKeyValueStore
 $value: array met content in eerste en attribuut in tweede subscript,
         volgende numerieke subscripts met waarde in rechterlid.
         Indien natuur van het attribuut = group, is er nog een subscript extra =
         de naam van het deelattribuut, en waarde in rechterlid
         Indien natuur van het attribuut = multi, is er nog een subscript extra
         met waarde in rechterlid
         Indien niet ingevuld wordt verwacht dat de waarden in
         CAkvsset($id,$content,$att,n) staan.
         Getransformeerde waarden worden in deze array geplaatst.
 $att: het te transformeren attribuut (set:attribuut).
       Indien niet ingevuld moet $id of $content ingevuld zijn
 $content: content id van te transformeren attribuut
           Indien leeg moet $id ingevuld zijn
 $id: de initiatie identifier die eventueel moet overlopen worden (zie m4_initKeyValueStore)
      Indien leeg moet $att en $content ingevuld zijn,
      ofwel enkel $content en dan worden alle in de meta-info van $content
      gespecificeerde attributen bewerkt
 $example: m4_transKeyValueStore(RAvalue,att,content)
           m4_transKeyValueStore(id=id)
 '''
 «d %Loop^bkvsexec(.$value,$att,$content,$id,"","","","","","trns")»

13.6.1.7. Testen

Het testen kan expliciet door de applicatie uitgevoerd worden. Zoniet, probeert m4_formatKeyValueStore automatisch de nodige testen te doen.

macro testKeyValueStore($value,$att="",$content="",$required="",$id=""):
 '''
 $synopsis: Test de waarde(n) van een attribuut,
            of een reeks attributen, geinitialiseerd met m4_initKeyValueStore
 $value: array met content in eerste en attribuut in tweede subscript,
         volgende numerieke subscripts met waarde in rechterlid.
         Indien niet ingevuld wordt verwacht dat de waarden in
         CAkvsset($id,$content,$att,n) staan.
 $att: het te testen attribuut (set:attribuut).
       Indien niet ingevuld moet $id of $content ingevuld zijn
 $content: content id van te testen attribuut
           Indien leeg moet $id ingevuld zijn
 $required: 1 = attribuut moet waarde hebben | 0
            Geen betekenis indien $id ingevuld is.
            In dat geval wordt daar gekeken naar "!" modifier.
 $id: de initiatie identifier die eventueel moet overlopen worden (zie m4_initKeyValueStore)
      Indien leeg moet $att en eventueel $content ingevuld zijn,
      ofwel enkel $content en dan worden alle in de meta-info van
      $content gespecificeerde attributen getest
 $example: m4_testKeyValueStore(RAvalue,att,content)
           m4_testKeyValueStore(id)
 '''
 «d %Loop^bkvsexec(.$value,$att,$content,$id,$required,"","","","","test")»

13.6.1.8. Bewaren

De macro probeert eerst uit te zoeken of er al een trans en een test voor de gevraagde gegevens uitgevoerd is. Is dit niet het geval dan wordt dit alsnog geprobeerd.

Indien bij de omgeving, waar de te bewaren attributen toe behoren, een global voor logging is weggeschreven, logt de macro automatisch alle veranderingen.

Als een gebruiker wordt meegegeven in $user, wordt een attribuut enkel bewaard indien deze gebruiker edit toegang heeft tot dit attribuut.

macro fileKeyValueStore($global="",$att="",$content="",$value="",$id="",$user="",
                        $access="",$sub="",$delete=0,$defset=1):
 '''
 $synopsis: Bewaar de waarde(n) van een attribuut,
            of een reeks attributen geinitialiseerd met m4_initKeyValueStore
            Opslag gebeurt in @$global@("kvs").
            Array CAkvsChg bevat de uitgevoerde wijzigingen in de vorm
            CAkvsChg($co ntent,"set",$att,n)=""
            CAkvsChg($content,"del",$att,n)=""
 $global: de globaltak waar de attributen moeten geplaatst worden.
          vb. ^BCAT("lvd",12345)
          Indien niet ingevuld wordt gekeken bij de meta-info van de omgeving
 $att: het te stockeren attribuut (set:attribuut). Indien niet ingevuld moet $id ingevuld zijn
 $content: content id van te stockeren attribuut
           Indien leeg moet $id ingevuld zijn
 $value: array met content in eerste en attribuut in tweede subscript,
         volgende numerieke subscripts met waarde in rechterlid.
         Indien niet ingevuld wordt verwacht dat de waarden in
         CAkvsset($id,$content,$att,n) staan.
 $id: de initiatie identifier die eventueel moet overlopen worden (zie m4_initKeyValueStore)
      Indien leeg moet ofwel $att en $content ingevuld zijn,
      ofwel enkel $content en dan worden alle in de meta-info van
      $content gespecificeerde attributen gefiled
 $user: Test of deze gebruiker attribu(u)t(en) wel mag editeren.
        Indien leeg wordt $g(UDuser) gebruikt. Indien nog altijd leeg wordt sowieso gefiled.
 $access: overrulet toegangssloten in meta-informatie van behandelde attribu(u)t(en)
          array met volgende mogelijke subscripts:
          edit: enkel editeerbaar voor opgesomde toegangssloten (delimiter=;)
          view: altijd bekijk-mode voor opgesomde toegangssloten
          hidden: altijd hidden voor opgesomde toegangssloten
 $sub: enkel van toepassing indien $global="".
       Bevat 'identifier', onderverdeeld met ':' (vb. loi) waarvan de delen
       overeenkomen met s1,s2,... in de globaldefinitie van de meta-info van de content,
       s0 met de volledige 'identifier'
 $delete: 1 = forceer delete.
 $defset: 1 = de attributen worden weggeschreven zonder set indien hun set =
          de default set van de content
 $example: m4_fileKeyValueStore(global,att,content,RAvalue)
           m4_fileKeyValueStore(global,id)
 '''
 «d %File^bkvsexec($global,$att,$content,.$value,$id,$user,.$access,$sub,$delete,$defset)»
Voorbeeld 1:bewaar attributen geinitialiseerd met FDid1.
def File:
 m4_fileKeyValueStore(id=FDid1,sub="een:twee:drie")
Voorbeeld 2:bewaar 2 specifieke attributen.
def File:
 m4_fileKeyValueStore(att="seteen:testbool",content="testeen",sub="een:twee:drie")
 m4_fileKeyValueStore(att="settwee:teststring",content="testtwee",sub="een:twee:drie")
Voorbeeld 3:bewaar de bij content testdrie gespecificeerde attributen.
def File:
 m4_fileKeyValueStore(content="testdrie",sub="een:twee:drie")

13.6.2. Logging

Logging gebeurt automatisch voor veranderde attributen van een omgeving, indien in de meta-info van die omgeving een logging-global is ingevuld.

De logginginformatie kan opgevraagd worden met:

macro statusKeyValueStore($log,$content,$pointer="",$from="",$to=$from,$user="",$type=""):
 '''
 $synopsis: Haal logging informatie op van een bepaalde content
 $log: array met een volgnummer als eerste subscript
       waarde = gebruiker^tijdstip^pointer
       onder subscript volgnummer staan de logging gegevens:
       content,set|del,attribuut,volgnummer attribuut
 $content: content
 $pointer: pointer zoals weggeschreven in $sub van m4_fileKeyValueStore
 $from: begintijdstip in $h formaat
 $to: eindtijdstip in $h formaat
 $user: enkel wijzigingen door deze gebruiker
 $type: c = enkel log(s) van aanmaak
        m = enkel log(s) van laatste wijziging
        Indien $type'="" en $pointer'="", tellen $from, $to en $user niet meer
 $example: m4_statusKeyValueStore(RAlog,content,pointer,from)
 '''
 «d %Status^bkvsexec(.$log,$content,$pointer,$from,$to,$user,$type)»

13.7. Interface

Een attribuut wordt met een default template getoond, tenzij een specifieke template is ingevuld in de meta-info van dat attribuut, en de macro m4_formatKeyValueStore voor dat attribuut wordt aangesproken met $default=0.

13.7.1. CSS

CSS klassen staan in qtech projecten /layout/.../keyvalue.css. Elk attribuut heeft volgende CSS-klassen, die voorrang krijgen al naargelang de volgorde in de CSS-file:

  • kvs_*attribuutnatuur*_*mode*: altijd aanwezig, vb. kvs_float_edit
  • kvs_*set*_*attribuut*_*mode*: altijd aanwezig, vb. kvs_seteen_testfloat_edit
  • kvs_*attribuutnatuur*_repeat_text: enkel indien attribuut herhaalbaar is d.m.v. textinput, waarden gescheiden door “;”
  • kvs_*attribuutnatuur*_repeat_area: enkel indien attribuut herhaalbaar is d.m.v. textarea

D.m.v. de klasse kvs_focus kan bepaald worden hoe een element dat de focus krijgt, er moet uitzien.

13.7.2. Contextmenu

Een rechter muisklik op een attribuut of begeleidend label, brengt een contextmenu te voorschijn met volgende mogelijkheden die naargelang de omstandigheden zichtbaar/aktief zijn:

  • Informatie: indien de scope bij het attribuut is ingevuld
  • Preview: indien markdown is toegelaten in het invulveld.
  • Wis: verwijder de ingevulde waarde
  • Up: indien het attribuut herhaalbaar is en het gekozen attribuut niet het eerste van de reeks is
  • Down: indien het attribuut herhaalbaar is en het gekozen attribuut niet het laatste van de reeks is
  • Dupliceer: indien het attribuut herhaalbaar is en bij de omgeving niet voor een dupliceerknop is gekozen. De actie maakt een nieuw, leeg, invulveld aan.
  • Kloon: indien het attribuut herhaalbaar is. De actie maakt een nieuw invulveld aan met dezelfde waarde als het gekozen attribuut
  • Quit: verberg het contextmenu

Voor groepen gelden de acties van het contextmenu altijd voor de volledige groep, niet voor individuele deelattributen.

13.8. Drag & drop

13.8.1. Drag & drop zones

In browsers die HTML5 ondersteunen zijn drag & drop acties van csv-structuren mogelijk.

In de omgeving kan gespecificeerd worden of een dropzone moet voorzien worden en of deze dropzone ook waarden van attributen van andere omgevingen mag ontvangen.
Bestaande waarden worden hierbij altijd overschreven, maar natuurlijk enkel in de interface. Registreren blijft noodzakelijk om de waarden effectief in de databank te plaatsen.

Ook kan aangegeven worden of de label van de omgeving ‘draggable’ is. Zo ja, dan creëert versleping ervan een csv-structuur die dan weer ergens anders kan gedropt worden, bvb. in de dropzone van een andere omgeving.

Met behulp van macro m4_formatKeyValueDropzone kan een globale dropzone in het formulier getekend worden, i.p.v. of samen met een dropzone per omgeving. De layout ervan wordt bepaald door css-klassen dropzone_form en dropzone_hover_form.

macro formatKeyValueDropzone($id="global", $encoding="latin1"):
    '''
    $editfile: /keyvalue/application/keyvalue.d
    $synopsis:  Teken een globale dropzone voor alle key/values. De verwoording van de 'legend' staat in .dropzoneglobal
    $id: identifier van de dropzone
    $encoding: encodering van de gedropte gegevens
    $example: m4_formatKeyValueDropzone()
    '''

    «<div id="dropzone_form" class="dropzone_form" data-spandrop="1" draggable="true" ondragstart="KEYVALUE.dragHandlerForm(event,';')">x4_varcode(dragdrop)</div>
    m4_jsSectionBegin
    DROPZONE.initialize("dropzone_form", KEYVALUE.dropzoneHandler, $encoding, "");
    m4_jsSectionEnd»

De gangbare manier, zoals o.a. toegepast in meta-informatie, is om de individuele dropzones van de omgevingen te verbergen met CSS, en een globale dropzone in de takenbalk te zetten.

Om 1 enkele content naar een ander formulier te verplaatsen kan de label ervan in de drag & dropzone gedropt worden. Om alle contents naar een ander formulier te verplaatsen kan de drag & drop zone zelf versleept worden.

Een niet versleepbaar attribuut krijgt in het ontvangende formulier de css-klasse kvs_drop_missing toegekend. Er wordt tevens een waarschuwing getoond bij versleping van de omgeving waartoe het attribuut behoort.

13.8.2. Layout van de csv-structuur

Kolom 1:

Omgeving

Kolom 2:

Leeg of groepattribuut

Kolom 3:

Attribuut of deelattribuut van groep

Kolom 4:
  • indien multi: eerste waarde van het attribuut uit kolom 3
  • indien table: identificatie van een cel van de tabel uit kolom 3
  • anders: waarde van attribuut uit kolom 3
Kolom 5 ev.:
  • indien multi: volgende waarde van het attribuut
  • indien table: waarde van de cel uit vorige kolom