Skip to content

Commit

Permalink
adding more showcases (#831)
Browse files Browse the repository at this point in the history
  • Loading branch information
kelly-thai authored Aug 27, 2024
1 parent f40f198 commit 4d19214
Show file tree
Hide file tree
Showing 11 changed files with 398 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
---
title: Build an M2M hosted service
description:
development: true
Title: Legend Model-to-Model Services & Hosting
Description: Example implementation of Legend Model-to-Model Services and Hosting
---

TODO: Some dummy description
152 changes: 152 additions & 0 deletions showcases/data/Essential/Querying/Having clause/code.pure
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
###Relational
Database example::store::MyDepartmentStore
(
Schema DepartmentStore
(
Table EmployeeDepartment
(
uid INTEGER PRIMARY KEY,
employeeName VARCHAR(100) NOT NULL,
department VARCHAR(100) NOT NULL
)
)
)


###Service
Service example::service::EmployeeAssignmentService
{
pattern: '/EmployeeAssignmentService';
ownership: DID { identifier: '' };
documentation: '';
autoActivateUpdates: true;
execution: Single
{
query: |example::model::EmployeeAssignment.all()->groupBy(
[
x|$x.name
],
[
agg(
x|$x.department,
x|$x->distinct()->count()
)
],
[
'Name',
'Distinct Departments'
]
)->filter(
row|$row.getInteger('Distinct Departments') > 1
);
mapping: example::mapping::EmployeeAssignmentMapping;
runtime: example::runtime::EmployeeAssignmentRuntime;
}
}


###Pure
Class example::model::EmployeeAssignment
{
name: String[1];
department: String[1];
}


###Mapping
Mapping example::mapping::EmployeeAssignmentMapping
(
*example::model::EmployeeAssignment: Relational
{
~primaryKey
(
[example::store::MyDepartmentStore]DepartmentStore.EmployeeDepartment.uid
)
~mainTable [example::store::MyDepartmentStore]DepartmentStore.EmployeeDepartment
name: [example::store::MyDepartmentStore]DepartmentStore.EmployeeDepartment.employeeName,
department: [example::store::MyDepartmentStore]DepartmentStore.EmployeeDepartment.department
}

testSuites:
[
TestSuite1:
{
function: |example::model::EmployeeAssignment.all()->project(
[
x|$x.name,
x|$x.department
],
[
'Name',
'Department'
]
);
tests:
[
Test1:
{
data:
[
example::store::MyDepartmentStore:
Relational
#{
DepartmentStore.EmployeeDepartment:
'uid,employeeName,department\n'+
'1001,Elsa,Electrical\n'+
'1002,Etienne,Electrical\n'+
'1003,Chidi,Cosmetics\n'+
'1004,Chidi,Cafe\n'+
'1005,Heidi,Haberdashery\n'+
'1006,Heidi,Homewares\n';
}#
];
asserts:
[
expectedAssertion:
EqualToJson
#{
expected:
ExternalFormat
#{
contentType: 'application/json';
data: '[\n {\n "Name": "Elsa",\n "Department": "Electrical"\n },\n {\n "Name": "Etienne",\n "Department": "Electrical"\n },\n {\n "Name": "Chidi",\n "Department": "Cosmetics"\n },\n {\n "Name": "Chidi",\n "Department": "Cafe"\n },\n {\n "Name": "Heidi",\n "Department": "Haberdashery"\n },\n {\n "Name": "Heidi",\n "Department": "Homewares"\n }\n]';
}#;
}#
];
}
];
}
]
)


###Connection
RelationalDatabaseConnection example::connection::MyDepartmentStoreConnection
{
store: example::store::MyDepartmentStore;
type: H2;
specification: LocalH2
{
testDataSetupSqls: [
'Create Schema if not exists DepartmentStore;\nDrop Table if exists DepartmentStore.EmployeeDepartment;\nCreate Table DepartmentStore.EmployeeDepartment (uid INTEGER, employeeName VARCHAR(100), department VARCHAR(100));\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1001,\'Elsa\',\'Electrical\');\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1002,\'Etienne\',\'Electrical\');\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1003,\'Chidi\',\'Cosmetics\');\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1004,\'Chidi\',\'Cafe\');\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1005,\'Heidi\',\'Haberdashery\');\nINSERT INTO DepartmentStore.EmployeeDepartment(uid,employeeName,department) VALUES (1006,\'Heidi\',\'Homewares\');'
];
};
auth: DefaultH2;
}


###Runtime
Runtime example::runtime::EmployeeAssignmentRuntime
{
mappings:
[
example::mapping::EmployeeAssignmentMapping
];
connections:
[
example::store::MyDepartmentStore:
[
connection_1: example::connection::MyDepartmentStoreConnection
]
];
}
13 changes: 13 additions & 0 deletions showcases/data/Essential/Querying/Having clause/info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
title: Having clause in Alloy
description: Using services to simulate HAVING in SQL statements
---

This project showcases how services can be used to simulate the same behavior as the HAVING clause in a typical SQL SELECT statement.
The service here behaves the same as if this query was run:
SELECT
username,
count(distinct(department))
FROM table
GROUP BY username
HAVING count(distinct(department)) > 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
###Text
Text showcase::model::README
{
type: markdown;
content: '---\ntitle: Super types\ndescription: This an example that shows how to use super types in your data model\n---\n\nThe showcase shows how you can add a super type to a class in your data model. Navigate to the \'Super Type\' profile and click on \'+\' to add a super type. \nIn this example, the class \'Animal\' has been added as a superclass in class \'Dog\'. The class \'Dog\' has inherited all properties from class \'Animal\'.';
}


###Pure
Class showcase::model::Dog extends showcase::model::Animal
{
breed: String[1];
}

Class showcase::model::Animal
{
name: String[1];
sound: String[1];
age: String[1];
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Super types
description:
development: true
description: This an example that shows how to use super types in your data model
---

TODO: Some dummy description
The showcase shows how you can add a super type to a class in your data model. Navigate to the 'Super Type' profile and click on '+' to add a super type.
In this example, the class 'Animal' has been added as a superclass in class 'Dog'. The class 'Dog' has inherited all properties from class 'Animal'.
28 changes: 18 additions & 10 deletions showcases/data/Store/Model Store/Mapping/service/basic/code.pure
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
###Data
Data data::IBMFirmData
Data data::MyFirmData
{
ExternalFormat
#{
contentType: 'application/json';
data: '{\n "employees": [\n {\n "firstName": "John",\n "lastName": "Smith"\n }\n ],\n "legalName": "IBM",\n "type": "llc"\n}';
data: '{\n "employees": [\n {\n "firstName": "John",\n "lastName": "Smith"\n }\n ],\n "legalName": "Business",\n "type": "llc"\n}';
}#
}


###Text
Text mapping::m2mREADME
{
type: plainText;
content: '---\nTitle: Legend Model-to-Model Services & Hosting\nDescription: Example implementation of Legend Model-to-Model Services and Hosting\n---\n\n# Overview\n\nTry out Legend Services! [Go to the guide!](https://legend.finos.org/docs/overview/legend-overview)\n\n# Use Legend to Create Model-to-Model Mapping, Services, and Hosting\n\n## Prerequisite\n\n## Modeling\nThe first step of this implementation involves creating models.\n\nFor the purposes of this showcase (and for any model-to-model service), you will need to create two models: one source model and one target model.\n\nBy doing this, you are able to take in input data and transform this data from source to target.\n\nIn this example, our input data is stored in JSON format in `data::MyFirmData`.\n\nOur JSON data is connected to via `mapping::FirmConnection`, and `mapping::FirmRuntime` uses the connection to map the data into the model.\n\nOur source models are `model::Firm` and `model::Person`.\n\nOur target models are `model::target::_Firm` and `model::target::_Person`\n\n## Model-to-Model Service\nServices contain three different components, as follows:\n1. Function: uses a graphFetch query to select the properties of the target class that should be mapped and returned in the JSON response\n 1a. In our example, our Function is located under `mapping::FirmService`\n2. Mapping: a standard model-to-model mapping\n 2a. In our example, our Mapping is located under `mapping::ModelToModelMapping`\n3. Runtime: connection types are JsonModel, XmlModel, and FlatData.\n 3a. In our example, our Runtime is a JsonModel, and is located under `mapping::FirmRuntime`';
}


###Service
Service mapping::FirmService
{
Expand Down Expand Up @@ -54,7 +62,7 @@ Service mapping::FirmService
ExternalFormat
#{
contentType: 'application/json';
data: '{\n "employees": [\n {\n "firstName": "John",\n "lastName": "Smith"\n }\n ],\n "legalName": "IBM",\n "type": "llc"\n}';
data: '{\n "employees": [\n {\n "firstName": "John",\n "lastName": "Smith"\n }\n ],\n "legalName": "Business",\n "type": "llc"\n}';
}#
]
]
Expand All @@ -72,7 +80,7 @@ Service mapping::FirmService
ExternalFormat
#{
contentType: 'application/json';
data: '{\n "myLegalName()": "my name is: IBM",\n "name": "IBM",\n "employees": [\n {\n "fullName": "John Smith"\n }\n ]\n}';
data: '{\n "myLegalName()": "my name is: Business",\n "name": "Business",\n "employees": [\n {\n "fullName": "John Smith"\n }\n ]\n}';
}#;
}#
]
Expand Down Expand Up @@ -222,7 +230,7 @@ Mapping mapping::ModelToModelMapping
}#
];
},
IBMData:
MyData:
{
doc: '';
data:
Expand All @@ -233,7 +241,7 @@ Mapping mapping::ModelToModelMapping
model::Firm:
Reference
#{
data::IBMFirmData
data::MyFirmData
}#
}#
];
Expand All @@ -246,12 +254,12 @@ Mapping mapping::ModelToModelMapping
ExternalFormat
#{
contentType: 'application/json';
data: '{\r\n "employees" : [ {\r\n "fullName" : "John Smith"\r\n } ],\r\n "name" : "IBM",\r\n "myLegalName()" : "my name is: IBM"\r\n}';
data: '{\r\n "employees" : [ {\r\n "fullName" : "John Smith"\r\n } ],\r\n "name" : "Business",\r\n "myLegalName()" : "my name is: Business"\r\n}';
}#;
}#
];
},
IBMData2:
MyData2:
{
doc: '';
data:
Expand All @@ -262,7 +270,7 @@ Mapping mapping::ModelToModelMapping
model::Firm:
Reference
#{
data::IBMFirmData
data::MyFirmData
}#
}#
];
Expand All @@ -275,7 +283,7 @@ Mapping mapping::ModelToModelMapping
ExternalFormat
#{
contentType: 'application/json';
data: '{\n "employees" : [ {\n "fullName" : "John Smith"\n } ],\n "name" : "IBM",\n "myLegalName()" : "my name is: IBM"\n}';
data: '{\n "employees" : [ {\n "fullName" : "John Smith"\n } ],\n "name" : "Business",\n "myLegalName()" : "my name is: Business"\n}';
}#;
}#
];
Expand Down
36 changes: 33 additions & 3 deletions showcases/data/Store/Model Store/Mapping/service/basic/info.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
---
title: Model To Model Service - Querying _Firm using json input
description: Mapping of Firm to _Firm with tests and a service fetching _Firm output
Title: Legend Model-to-Model Services & Hosting
Description: Example implementation of Legend Model-to-Model Services and Hosting
---

This project showcases a model to model mapping from `Firm` to `_Firm` outlining a mapping test and a service test for model to model.
# Overview

Try out Legend Services! [Go to the guide!](https://legend.finos.org/docs/overview/legend-overview)

# Use Legend to Create Model-to-Model Mapping, Services, and Hosting

## Prerequisite

## Modeling
The first step of this implementation involves creating models.

For the purposes of this showcase (and for any model-to-model service), you will need to create two models: one source model and one target model.

By doing this, you are able to take in input data and transform this data from source to target.

In this example, our input data is stored in JSON format in `data::MyFirmData`.

Our JSON data is connected to via `mapping::FirmConnection`, and `mapping::FirmRuntime` uses the connection to map the data into the model.

Our source models are `model::Firm` and `model::Person`.

Our target models are `model::target::_Firm` and `model::target::_Person`

## Model-to-Model Service
Services contain three different components, as follows:
1. Function: uses a graphFetch query to select the properties of the target class that should be mapped and returned in the JSON response
1a. In our example, our Function is located under `mapping::FirmService`
2. Mapping: a standard model-to-model mapping
2a. In our example, our Mapping is located under `mapping::ModelToModelMapping`
3. Runtime: connection types are JsonModel, XmlModel, and FlatData.
3a. In our example, our Runtime is a JsonModel, and is located under `mapping::FirmRuntime`
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
###Relational
Database showcase::store::DemoStore
(
Table Person
(
id INTEGER PRIMARY KEY,
firm_id INTEGER,
firstName VARCHAR(200),
lastName VARCHAR(200)
)
)


###Text
Text showcase::README
{
type: markdown;
content: '---\ntitle: Postgres Connection\ndescription: Showcase of Postgres connection\n---\n\n Feature: Postgres connection is defined when we need to read data from Postgres.\n Usage: Define a new connection and choose Connection Type as "Relational Connection", Database Type as "Postgres". Add database specifications - host, port, db name. Also mention the authentication strategy.';
}


###Connection
RelationalDatabaseConnection showcase::connection::PostgresConnection
{
store: showcase::store::DemoStore;
type: Postgres;
specification: Static
{
name: 'DemoStore';
host: 'url.here';
port: 480;
};
auth: DelegatedKerberos
{
serverPrincipal: 'kerberos';
};
}
Loading

0 comments on commit 4d19214

Please sign in to comment.