/* * QQQ - Low-code Application Framework for Engineers. * Copyright (C) 2021-2022. Kingsrook, LLC * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States * contact@kingsrook.com * https://github.com/Kingsrook/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package com.kingsrook.sampleapp; import java.util.List; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.interfaces.mock.MockBackendStep; import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.QCodeType; import com.kingsrook.qqq.backend.core.model.metadata.QCodeUsage; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionOutputMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QRecordListMetaData; import com.kingsrook.qqq.backend.module.filesystem.base.model.metadata.Cardinality; import com.kingsrook.qqq.backend.module.filesystem.base.model.metadata.RecordFormat; import com.kingsrook.qqq.backend.module.filesystem.local.model.metadata.FilesystemBackendMetaData; import com.kingsrook.qqq.backend.module.filesystem.local.model.metadata.FilesystemTableBackendDetails; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; /******************************************************************************* ** *******************************************************************************/ public class SampleMetaDataProvider { public static final String MYSQL_BACKEND_NAME = "mysql"; public static final String FILESYSTEM_BACKEND_NAME = "filesystem"; public static final String PROCESS_NAME_GREET = "greet"; public static final String PROCESS_NAME_GREET_INTERACTIVE = "greetInteractive"; /******************************************************************************* ** *******************************************************************************/ public static QInstance defineInstance() throws QException { QInstance qInstance = new QInstance(); qInstance.setAuthentication(defineAuthentication()); qInstance.addBackend(defineMysqlBackend()); qInstance.addBackend(defineFilesystemBackend()); qInstance.addTable(defineTableCarrier()); qInstance.addTable(defineTablePerson()); qInstance.addTable(defineTableCityFile()); qInstance.addProcess(defineProcessGreetPeople()); qInstance.addProcess(defineProcessGreetPeopleInteractive()); return (qInstance); } /******************************************************************************* ** *******************************************************************************/ private static QAuthenticationMetaData defineAuthentication() { return new QAuthenticationMetaData() .withName("Anonymous") .withType("fullyAnonymous"); } /******************************************************************************* ** *******************************************************************************/ public static QBackendMetaData defineMysqlBackend() { return new RDBMSBackendMetaData() .withVendor("mysql") .withHostName("127.0.0.1") .withPort(3306) .withDatabaseName("sample_project") .withUsername("root") .withPassword("8BNWyoav8s79oi}Lqk") // todo - load securely .withName(MYSQL_BACKEND_NAME); } /******************************************************************************* ** *******************************************************************************/ public static FilesystemBackendMetaData defineFilesystemBackend() { return new FilesystemBackendMetaData() .withBasePath("/tmp/sample-filesystem") .withName(FILESYSTEM_BACKEND_NAME); } /******************************************************************************* ** *******************************************************************************/ public static QTableMetaData defineTableCarrier() { QTableMetaData table = new QTableMetaData(); table.setName("carrier"); table.setBackendName(MYSQL_BACKEND_NAME); table.setPrimaryKeyField("id"); table.addField(new QFieldMetaData("id", QFieldType.INTEGER)); table.addField(new QFieldMetaData("name", QFieldType.STRING)); table.addField(new QFieldMetaData("company_code", QFieldType.STRING) // todo enum .withLabel("Company") .withBackendName("comp_code")); table.addField(new QFieldMetaData("service_level", QFieldType.STRING)); // todo enum return (table); } /******************************************************************************* ** *******************************************************************************/ public static QTableMetaData defineTablePerson() { return new QTableMetaData() .withName("person") .withLabel("Person") .withBackendName(MYSQL_BACKEND_NAME) .withPrimaryKeyField("id") .withField(new QFieldMetaData("id", QFieldType.INTEGER)) .withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withBackendName("create_date")) .withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withBackendName("modify_date")) .withField(new QFieldMetaData("firstName", QFieldType.STRING).withBackendName("first_name")) .withField(new QFieldMetaData("lastName", QFieldType.STRING).withBackendName("last_name")) .withField(new QFieldMetaData("birthDate", QFieldType.DATE).withBackendName("birth_date")) .withField(new QFieldMetaData("email", QFieldType.STRING)); } /******************************************************************************* ** *******************************************************************************/ public static QTableMetaData defineTableCityFile() { return new QTableMetaData() .withName("city") .withLabel("Cities") .withBackendName(FILESYSTEM_BACKEND_NAME) .withPrimaryKeyField("id") .withField(new QFieldMetaData("id", QFieldType.INTEGER)) .withField(new QFieldMetaData("name", QFieldType.STRING)) .withField(new QFieldMetaData("state", QFieldType.STRING)) // todo - state PVS. .withBackendDetails(new FilesystemTableBackendDetails() .withBasePath("cities") .withCardinality(Cardinality.MANY) .withRecordFormat(RecordFormat.CSV) ); } /******************************************************************************* ** Define the 'greet people' process *******************************************************************************/ private static QProcessMetaData defineProcessGreetPeople() { return new QProcessMetaData() .withName(PROCESS_NAME_GREET) .withLabel("Greet People") .withTableName("person") .addStep(new QBackendStepMetaData() .withName("prepare") .withCode(new QCodeReference() .withName(MockBackendStep.class.getName()) .withCodeType(QCodeType.JAVA) .withCodeUsage(QCodeUsage.FUNCTION)) // todo - needed, or implied in this context? .withInputData(new QFunctionInputMetaData() .withRecordListMetaData(new QRecordListMetaData().withTableName("person")) .withFieldList(List.of( new QFieldMetaData("greetingPrefix", QFieldType.STRING), new QFieldMetaData("greetingSuffix", QFieldType.STRING) ))) .withOutputMetaData(new QFunctionOutputMetaData() .withRecordListMetaData(new QRecordListMetaData() .withTableName("person") .addField(new QFieldMetaData("fullGreeting", QFieldType.STRING)) ) .withFieldList(List.of(new QFieldMetaData("outputMessage", QFieldType.STRING)))) ); } /******************************************************************************* ** Define an interactive version of the 'greet people' process *******************************************************************************/ private static QProcessMetaData defineProcessGreetPeopleInteractive() { return new QProcessMetaData() .withName(PROCESS_NAME_GREET_INTERACTIVE) .withTableName("person") .addStep(new QFrontendStepMetaData() .withName("setup") .withFormField(new QFieldMetaData("greetingPrefix", QFieldType.STRING)) .withFormField(new QFieldMetaData("greetingSuffix", QFieldType.STRING)) ) .addStep(new QBackendStepMetaData() .withName("doWork") .withCode(new QCodeReference() .withName(MockBackendStep.class.getName()) .withCodeType(QCodeType.JAVA) .withCodeUsage(QCodeUsage.FUNCTION)) // todo - needed, or implied in this context? .withInputData(new QFunctionInputMetaData() .withRecordListMetaData(new QRecordListMetaData().withTableName("person")) .withFieldList(List.of( new QFieldMetaData("greetingPrefix", QFieldType.STRING), new QFieldMetaData("greetingSuffix", QFieldType.STRING) ))) .withOutputMetaData(new QFunctionOutputMetaData() .withRecordListMetaData(new QRecordListMetaData() .withTableName("person") .addField(new QFieldMetaData("fullGreeting", QFieldType.STRING)) ) .withFieldList(List.of(new QFieldMetaData("outputMessage", QFieldType.STRING)))) ) .addStep(new QFrontendStepMetaData() .withName("results") .withFormField(new QFieldMetaData("outputMessage", QFieldType.STRING)) ); } }