Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Handle subtypes in query builder #630

Closed
8 tasks done
Tracked by #256
akphi opened this issue Oct 30, 2021 · 3 comments
Closed
8 tasks done
Tracked by #256

Feature request: Handle subtypes in query builder #630

akphi opened this issue Oct 30, 2021 · 3 comments
Assignees
Labels
Component: Query Builder Issues related to query builder core Studio Core Team Opened by a member of the Studio core team Type: Feature Request
Milestone

Comments

@akphi
Copy link
Contributor

akphi commented Oct 30, 2021

Similar requests

  • I have searched and found no existing similar requests

What problems are you trying to solve?

In query builder, in the explorer tree, we should be able to navigate properties coming from sub-types.

Describe the solution you would like to see implemented

Firm (+)
  |__ employees: Person (+)
  |       |__ name: String
  |       |__ ProductManager (+)
  |       |       |__ product
  |       |__ Technologist (+)
  |       |       |__ techID
  |       |__ Studio Technologist (+)
  |               |__ githubID
  |__ legalName: String
  |
  |__ @Startup
          |__ fundingRound: FundingRound

Where we have:
Startup extends Firm
ProductManager extends Person
Technologist extends Person
StudioTechnologist extends Technologist

Feature Video

demo.mov

Example Grammar

The template model used in the video above:

###Service
Service model::MyService
{
  pattern: '/d2c48a9c-70fa-46e3-8173-c355e774004f';
  documentation: '';
  autoActivateUpdates: true;
  execution: Single
  {
    query: |model::Firm.all()->project([x|$x.employeeSize, x|$x.legalName], ['Employee Size', 'Legal Name']);
    mapping: model::NewMapping;
    runtime: model::Runtime;
  }
  test: Single
  {
    data: '';
    asserts:
    [
    ];
  }
}


###Relational
Database model::Test
(
  Table FirmTable
  (
    id INTEGER PRIMARY KEY,
    Legal_name VARCHAR(200)
  )
  Table PersonTable
  (
    id INTEGER PRIMARY KEY,
    firm_id INTEGER,
    firstName VARCHAR(200),
    lastName VARCHAR(200)
  )
  Table AddressTable
  (
    id INTEGER PRIMARY KEY,
    firm_id INTEGER,
    name VARCHAR(200)
  )

  Join FirmPerson(PersonTable.firm_id = FirmTable.id)
  Join FirmAddress(AddressTable.firm_id = FirmTable.id)
)


###Pure
Profile model::MyExtension
{
  stereotypes: [important];
  tags: [doc];
}

Enum model::IncType
{
  Corp,
  LLC
}

Class model::LegalEntity
{
  legalName: String[1];
  address: model::Address[1];
}

Class <<model::MyExtension.important>> {model::MyExtension.doc = 'This is a model of a firm'} model::Firm extends model::LegalEntity
[
  validName: $this.legalName->startsWith('_')
]
{
  employees: model::Person[1..*];
  incType: model::IncType[1];
  employeeSize() {$this.employees->count()}: Number[1];
}

Class model::Person
{
  firstName: String[1];
  lastName: String[1];
}

Class model::Address
{
  zipcode: Integer[1];
}

Class model::Street extends model::Address
{
  streetName: String[1];
}


###Mapping
Mapping model::NewMapping
(
  *model::Firm extends [model_LegalEntity]: Relational
  {
    ~primaryKey
    (
      [model::Test]FirmTable.id
    )
    ~mainTable [model::Test]FirmTable
    employees[model_Person]: [model::Test]@FirmPerson
  }
  *model::Person: Relational
  {
    ~primaryKey
    (
      [model::Test]PersonTable.id
    )
    ~mainTable [model::Test]PersonTable
    firstName: [model::Test]PersonTable.firstName,
    lastName: [model::Test]PersonTable.lastName
  }
  *model::LegalEntity: Relational
  {
    ~primaryKey
    (
      [model::Test]FirmTable.id
    )
    ~mainTable [model::Test]FirmTable
    legalName: [model::Test]FirmTable.Legal_name,
    address[model_Address]: [model::Test]@FirmAddress
  }
  *model::Address: Relational
  {
    ~primaryKey
    (
      [model::Test]AddressTable.id
    )
    ~mainTable [model::Test]AddressTable
    zipcode: [model::Test]AddressTable.id
  }
)


###Connection
RelationalDatabaseConnection model::MyC
{
  store: model::Test;
  type: H2;
  specification: LocalH2
  {
    testDataSetupSqls: [
      'Drop table if exists FirmTable;\r\nDrop table if exists PersonTable;\r\nCreate Table FirmTable(id INT, Legal_Name VARCHAR(200));\r\nCreate Table PersonTable(id INT, firm_id INT, lastName VARCHAR(200), firstName VARCHAR(200));\r\nInsert into FirmTable (id, Legal_Name) values (1, \'FirmX\');\r\nInsert into PersonTable (id, firm_id, lastName, firstName) values (1, 1, \'John\', \'Doe\');\r\n'
      ];
  };
  auth: DefaultH2;
}


###Runtime
Runtime model::Runtime
{
  mappings:
  [
    model::NewMapping
  ];
  connections:
  [
    model::Test:
    [
      connection_1: model::MyC
    ]
  ];
}
@akphi akphi added this to the 2.0.0 milestone Oct 30, 2021
@github-actions github-actions bot added the Studio Core Team Opened by a member of the Studio core team label Oct 30, 2021
@akphi akphi added the Component: Query Builder Issues related to query builder core label Oct 30, 2021
@akphi akphi modified the milestones: 2.0.0, 3.0.0 Nov 22, 2021
@YannanGao-gs YannanGao-gs reopened this Jan 7, 2022
@github-actions github-actions bot modified the milestones: 3.0.0, 4.0.0 Feb 4, 2022
@njerigrevious njerigrevious modified the milestones: 4.0.0, 3.0.0 Feb 8, 2022
@YannanGao-gs
Copy link
Contributor

Demo video:

demo.mov

@YannanGao-gs
Copy link
Contributor

The template model used in the video above:

###Service
Service model::MyService
{
  pattern: '/d2c48a9c-70fa-46e3-8173-c355e774004f';
  documentation: '';
  autoActivateUpdates: true;
  execution: Single
  {
    query: |model::Firm.all()->project([x|$x.employeeSize, x|$x.legalName], ['Employee Size', 'Legal Name']);
    mapping: model::NewMapping;
    runtime: model::Runtime;
  }
  test: Single
  {
    data: '';
    asserts:
    [
    ];
  }
}


###Relational
Database model::Test
(
  Table FirmTable
  (
    id INTEGER PRIMARY KEY,
    Legal_name VARCHAR(200)
  )
  Table PersonTable
  (
    id INTEGER PRIMARY KEY,
    firm_id INTEGER,
    firstName VARCHAR(200),
    lastName VARCHAR(200)
  )
  Table AddressTable
  (
    id INTEGER PRIMARY KEY,
    firm_id INTEGER,
    name VARCHAR(200)
  )

  Join FirmPerson(PersonTable.firm_id = FirmTable.id)
  Join FirmAddress(AddressTable.firm_id = FirmTable.id)
)


###Pure
Profile model::MyExtension
{
  stereotypes: [important];
  tags: [doc];
}

Enum model::IncType
{
  Corp,
  LLC
}

Class model::LegalEntity
{
  legalName: String[1];
  address: model::Address[1];
}

Class <<model::MyExtension.important>> {model::MyExtension.doc = 'This is a model of a firm'} model::Firm extends model::LegalEntity
[
  validName: $this.legalName->startsWith('_')
]
{
  employees: model::Person[1..*];
  incType: model::IncType[1];
  employeeSize() {$this.employees->count()}: Number[1];
}

Class model::Person
{
  firstName: String[1];
  lastName: String[1];
}

Class model::Address
{
  zipcode: Integer[1];
}

Class model::Street extends model::Address
{
  streetName: String[1];
}


###Mapping
Mapping model::NewMapping
(
  *model::Firm extends [model_LegalEntity]: Relational
  {
    ~primaryKey
    (
      [model::Test]FirmTable.id
    )
    ~mainTable [model::Test]FirmTable
    employees[model_Person]: [model::Test]@FirmPerson
  }
  *model::Person: Relational
  {
    ~primaryKey
    (
      [model::Test]PersonTable.id
    )
    ~mainTable [model::Test]PersonTable
    firstName: [model::Test]PersonTable.firstName,
    lastName: [model::Test]PersonTable.lastName
  }
  *model::LegalEntity: Relational
  {
    ~primaryKey
    (
      [model::Test]FirmTable.id
    )
    ~mainTable [model::Test]FirmTable
    legalName: [model::Test]FirmTable.Legal_name,
    address[model_Address]: [model::Test]@FirmAddress
  }
  *model::Address: Relational
  {
    ~primaryKey
    (
      [model::Test]AddressTable.id
    )
    ~mainTable [model::Test]AddressTable
    zipcode: [model::Test]AddressTable.id
  }
)


###Connection
RelationalDatabaseConnection model::MyC
{
  store: model::Test;
  type: H2;
  specification: LocalH2
  {
    testDataSetupSqls: [
      'Drop table if exists FirmTable;\r\nDrop table if exists PersonTable;\r\nCreate Table FirmTable(id INT, Legal_Name VARCHAR(200));\r\nCreate Table PersonTable(id INT, firm_id INT, lastName VARCHAR(200), firstName VARCHAR(200));\r\nInsert into FirmTable (id, Legal_Name) values (1, \'FirmX\');\r\nInsert into PersonTable (id, firm_id, lastName, firstName) values (1, 1, \'John\', \'Doe\');\r\n'
      ];
  };
  auth: DefaultH2;
}


###Runtime
Runtime model::Runtime
{
  mappings:
  [
    model::NewMapping
  ];
  connections:
  [
    model::Test:
    [
      connection_1: model::MyC
    ]
  ];
}

@akphi
Copy link
Contributor Author

akphi commented Feb 10, 2022

@YannanGao-gs btw, did you handle ->subType(...).someSupertypeProperty ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Query Builder Issues related to query builder core Studio Core Team Opened by a member of the Studio core team Type: Feature Request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants