Entitäten
Physikalische Entitäten
Aus der Definition wird beim Laden des Paketes eine Tabelle im Postgres erstellt. Alle definierten Indices und Felder werden angelegt und bei Änderungen upgedatet.
Die Standardfelder uuid
, version
, createdAt
, createdBy
, updatedAt
und updatedBy
werden automatisch angelegt.
Default-Values und Index-Expression sehen ggf. im Postgres anders aus als im Package angegeben.
Dadurch kann es zu unnötigen Updates der Tabelle/des Index kommen. In solchen Fällen, muss
per pgAdmin untersucht werden woher der Unterschied kommt, damit es Package gleich gemacht werden kann.
...
packageKey: PK
objects:
entities:
- entityName: PK_MyEntity
primaryKeyName: uuid
type: dbTable
source: beng
managed: true
permissions:
read:
- role: PK.user
create:
- role: PK.admin
# Das Feld `userName` wird in der Tabelle zu `user_name`.
# Der Index muss die Feldnamen der Tabelle verwenden.
indices:
- name: user_name
isUnique: true
columns:
- name: "{{userName:columnName}}"
order: DESC
- expression: LEFT({{userName:columnName}}, 10)
order: DESC
nulls: FIRST
fields:
- name: age
label: Alter
dbType: integer
isNullable: false
defaultValue: 18
- name: userName
label: Benutzername
dbType: text
- name: mySpaceId
label: mySpace
deprecated: true
Views
Beispiel-Entität ArbeitsZeitArtikel
Folgendes Beispiel definiert eine Entität ArbeitsZeitArtikel
. Die Datengrundlage ist ein View, welcher alle Arbeitszeit-Artikel beinhaltet und nur wenige Felder der Dab010
enthält.
Beispielhafte YAML-Definition:
entityName: ArbeitsZeitArtikel
primaryKeyName: ID
viewDefinition:
pgSql: |
SELECT ID, MATCHCODE, ARTNR, ARTTYP
FROM data.dab010
WHERE ARTTYP = 'A'
fields:
- name: ID
label: ID
dbType: integer
- name: MATCHCODE
label: Matchcode
dbType: character
- name: ARTNR
label: Artikelnummer
dbType: character
- name: ARTTYP
label: Artikeltyp
dbType: character
dbLength: 1
permissions:
read:
- role: admin
- role: user
filter: dab010.ARTTYP = 'A'
create:
- role: admin
update:
- role: admin
- role: user
delete:
- role: admin
Über die Eigenschaft permissions
wird gesteuert, welche Rolle benötigt wird, um die gegebene Aktion auszuführen. Ohne Rollenangabe ist die Aktion nur für Benutzer mit der Rolle admin
des definierenden Packages ausführbar.
Pro Rolle kann außerdem ein statischer SQL Filter angegeben werden. Sobald einer der Berichtigungsfilter zutrifft, ist der Zugriff auf die Daten gegeben. Beim Ändern und Löschen von Daten muss sowohl die entsprechende Berechtigung als auch die Leseberechtigung gegeben sein.
Eine Entität (“einzelner Datensatz”) die über die OData-Schnittstelle abgerufen wird, sieht zum Beispiel so aus:
{
"@odata.context": "http://<tenant>.businessexpress.cloud/odata/v4/$metadata#ArbeitsZeitArtikle/$entity",
"ID": 40,
"MATCHCODE": "A_ZUSCHNEIDEN",
"ARTNR": "A_ZUSCHNEIDEN",
"ARTTYP": "A"
}
und eine EntityCollection (“mehrere Datensätze”) so:
{
"@odata.context": "http://<tenant>.businessexpress.cloud/odata/v4/$metadata#ArbeitsZeitArtikel",
"value": [
{
"ID": 71,
"MATCHCODE": "A_DREHEN_KLEIN",
"ARTNR": "A_DREHEN_KLEIN",
"ARTTYP": "A"
},
{
"ID": 73,
"MATCHCODE": "A_DREHEN_GROSS",
"ARTNR": "A_DREHEN_GROSS",
"ARTTYP": "A"
},
{
"ID": 126,
"MATCHCODE": "A_DREHEN_GROSS",
"ARTNR": "A_DREHEN_GROSS",
"ARTTYP": "A"
},
{
"ID": 127,
"MATCHCODE": "A_DREHEN_KLEIN",
"ARTNR": "A_DREHEN_KLEIN",
"ARTTYP": "A"
}
]
}
Views mit Bearbeitung im Codeblock
Beispiel-Entität Artikelgruppen
Folgendes Beispiel definiert eine Entität Artikelgruppen
. Die Datengrundlage ist ein View, welcher alle Artikelgruppen beinhaltet und nur wenige Felder der Dab310
enthält.
Beispielhafte YAML-Definition:
entityName: Artikelgruppen
type: dbView
source: be
primaryKeyName: id
permissions:
read:
- role: admin
update:
- role: admin
create:
- role: admin
delete:
- role: admin
fields:
- name: id
dbType: integer
label: ID
tableName: Dab310
isPrimaryKey: true
- name: group_number
dbType: text
label: Artikel-Gruppe-Nr.
tableName: Dab310
- name: bez1
dbType: text
label: Bezeichnung
tableName: Dab310
viewDefinition:
pgSql: |
SELECT
id,
artgruppe as group_number,
bez1
FROM data.dab310
Bei einem GET
-Request werden die Daten wie bei https://dontenwill.atlassian.net/wiki/spaces/BPOH/pages/edit-v2/38666303#Views aus einem Datenbank-View gelesen.
Die Methoden POST
, PATCH
und DELETE
werden im Codeblock bearbeitet.
Es werden entsprechend die Funktionen Method_POST
, Method_PATCH
und Method_DELETE
im Programm mit dem Schema be-portal\.customizing\<tableName>\implementation
aufgerufen.
In unserem Beispiel würde es im Programm be-portal\.customizing\Dab310\implementation
wie folgt aussehen.
| oDM:P1, oHeaders:P2 |
//******************************************************************************
// Implementierung für die HTTP-Methode POST (Neuanlage eines Datensatzes)
// @Result: null
//******************************************************************************
function Method_POST(oBody)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'ARTIKELGRUPPEN' ::
oDab310 := DBGetTable(oDM, waDab310),
oDab310.CbInsert(),
oDab310:ARTGRUPPE := oBody.getString('group_number'),
oDab310:BEZ1 := oBody.getString('bez1'),
oDab310.CbPost(),
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,
//******************************************************************************
// Implementierung für die HTTP-Methode PATCH (Aktualisierung eines Datensatzes)
// @Result: null
//******************************************************************************
function Method_PATCH(uIdentifier, oBody)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'ARTIKELGRUPPEN' ::
oDab310 := DBGetTable(oDM, waDab310),
oDab310.CbIndexName := 'ID',
if (oDab310.CbFindKey({uIdentifier})) then
oDab310.CbEdit(),
oDab310:BEZ1 := oBody.getString('bez1'),
oDab310.CbPost(),
else
SetError('record with id ' + uIdentifier + ' not found'),
endif,
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,
//******************************************************************************
// Implementierung für die HTTP-Methode DELETE (Löschen eines Datensatzes)
// @Result: null
//******************************************************************************
function Method_DELETE(uIdentifier)
| oDab310 |
case Upper(oHeaders.getString('entity-name'))
of 'ARTIKELGRUPPEN' ::
oDab310 := MyGetTable(oDM, waDab310),
oDab310.CbIndexName := 'ID',
if (oDab310.CbFindKey({uIdentifier})) then
MyDelete(oDab310),
else
SetError('record with id ' + uIdentifier + ' not found'),
endif,
otherwise
SetError('no implementation for entity ' + oHeaders.getString('entity-name')),
endcase,
end,