From d8a0a6c68d00ee27308db29e5a1b661d64fdf915 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Tue, 12 Nov 2024 09:43:17 -0600 Subject: [PATCH] CE-1955 Move prime-test-database into mainline, to be loaded when javalin starts --- qqq-sample-project/pom.xml | 1 - .../sampleapp/SampleJavalinServer.java | 2 + .../metadata/SampleMetaDataProvider.java | 184 +++++++++++++++++- .../resources/prime-test-database.sql | 21 ++ 4 files changed, 206 insertions(+), 2 deletions(-) rename qqq-sample-project/src/{test => main}/resources/prime-test-database.sql (82%) diff --git a/qqq-sample-project/pom.xml b/qqq-sample-project/pom.xml index d7e8e2bf..2ff7aee7 100644 --- a/qqq-sample-project/pom.xml +++ b/qqq-sample-project/pom.xml @@ -74,7 +74,6 @@ com.h2database h2 2.2.220 - test diff --git a/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/SampleJavalinServer.java b/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/SampleJavalinServer.java index 7ec4a911..37f3e3d1 100644 --- a/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/SampleJavalinServer.java +++ b/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/SampleJavalinServer.java @@ -64,6 +64,8 @@ public class SampleJavalinServer { qInstance = SampleMetaDataProvider.defineInstance(); + SampleMetaDataProvider.primeTestDatabase("prime-test-database.sql"); + QJavalinImplementation qJavalinImplementation = new QJavalinImplementation(qInstance); javalinService = Javalin.create(config -> { diff --git a/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/metadata/SampleMetaDataProvider.java b/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/metadata/SampleMetaDataProvider.java index ec2aa618..37526837 100644 --- a/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/metadata/SampleMetaDataProvider.java +++ b/qqq-sample-project/src/main/java/com/kingsrook/sampleapp/metadata/SampleMetaDataProvider.java @@ -22,7 +22,10 @@ package com.kingsrook.sampleapp.metadata; +import java.io.InputStream; import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,7 +40,10 @@ import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepInpu import com.kingsrook.qqq.backend.core.model.actions.processes.RunBackendStepOutput; import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerHelper; import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType; +import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.audits.AuditLevel; +import com.kingsrook.qqq.backend.core.model.metadata.audits.QAuditRules; import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData; import com.kingsrook.qqq.backend.core.model.metadata.branding.QBrandingMetaData; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; @@ -48,8 +54,13 @@ import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QuickSightChartMe import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; +import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn; +import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType; +import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData; import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppMetaData; import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; +import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PossibleValueEnum; +import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource; import com.kingsrook.qqq.backend.core.model.metadata.processes.QBackendStepMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QComponentType; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData; @@ -58,6 +69,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QFunctionInputMet 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.core.model.metadata.tables.Association; import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; @@ -70,9 +82,13 @@ import com.kingsrook.qqq.backend.module.filesystem.base.model.metadata.Cardinali 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.filesystem.s3.model.metadata.S3TableBackendDetails; +import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; +import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; import com.kingsrook.sampleapp.dashboard.widgets.PersonsByCreateDateBarChart; import com.kingsrook.sampleapp.processes.clonepeople.ClonePeopleTransformStep; +import org.apache.commons.io.IOUtils; /******************************************************************************* @@ -80,7 +96,7 @@ import com.kingsrook.sampleapp.processes.clonepeople.ClonePeopleTransformStep; *******************************************************************************/ public class SampleMetaDataProvider { - public static boolean USE_MYSQL = true; + public static boolean USE_MYSQL = false; public static final String RDBMS_BACKEND_NAME = "rdbms"; public static final String FILESYSTEM_BACKEND_NAME = "filesystem"; @@ -97,6 +113,7 @@ public class SampleMetaDataProvider public static final String PROCESS_NAME_SLEEP_INTERACTIVE = "sleepInteractive"; public static final String TABLE_NAME_PERSON = "person"; + public static final String TABLE_NAME_PET = "pet"; public static final String TABLE_NAME_CARRIER = "carrier"; public static final String TABLE_NAME_CITY = "city"; @@ -106,6 +123,9 @@ public class SampleMetaDataProvider public static final String SCREEN_0 = "screen0"; public static final String SCREEN_1 = "screen1"; + public static final String BACKEND_NAME_UPLOAD_ARCHIVE = "uploadArchive"; + public static final String UPLOAD_FILE_ARCHIVE_TABLE_NAME = "uploadFileArchive"; + /******************************************************************************* @@ -120,6 +140,10 @@ public class SampleMetaDataProvider qInstance.addBackend(defineFilesystemBackend()); qInstance.addTable(defineTableCarrier()); qInstance.addTable(defineTablePerson()); + qInstance.addPossibleValueSource(QPossibleValueSource.newForTable(TABLE_NAME_PERSON)); + qInstance.addPossibleValueSource(QPossibleValueSource.newForEnum(PetSpecies.NAME, PetSpecies.values())); + qInstance.addTable(defineTablePet()); + qInstance.addJoin(defineTablePersonJoinPet()); qInstance.addTable(defineTableCityFile()); qInstance.addProcess(defineProcessGreetPeople()); qInstance.addProcess(defineProcessGreetPeopleInteractive()); @@ -128,6 +152,9 @@ public class SampleMetaDataProvider qInstance.addProcess(defineProcessScreenThenSleep()); qInstance.addProcess(defineProcessSimpleThrow()); + qInstance.add(defineUploadArchiveBackend()); + qInstance.add(defineTableUploadFileArchive()); + MetaDataProducerHelper.processAllMetaDataProducersInPackage(qInstance, SampleMetaDataProvider.class.getPackageName()); defineWidgets(qInstance); @@ -139,6 +166,26 @@ public class SampleMetaDataProvider + /******************************************************************************* + ** + *******************************************************************************/ + public static void primeTestDatabase(String sqlFileName) throws Exception + { + try(Connection connection = ConnectionManager.getConnection(SampleMetaDataProvider.defineRdbmsBackend())) + { + InputStream primeTestDatabaseSqlStream = SampleMetaDataProvider.class.getResourceAsStream("/" + sqlFileName); + List lines = IOUtils.readLines(primeTestDatabaseSqlStream, StandardCharsets.UTF_8); + lines = lines.stream().filter(line -> !line.startsWith("-- ")).toList(); + String joinedSQL = String.join("\n", lines); + for(String sql : joinedSQL.split(";")) + { + QueryManager.executeUpdate(connection, sql); + } + } + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -192,6 +239,7 @@ public class SampleMetaDataProvider .withIcon(new QIcon().withName("emoji_people")) .withChild(qInstance.getProcess(PROCESS_NAME_GREET).withIcon(new QIcon().withName("emoji_people"))) .withChild(qInstance.getTable(TABLE_NAME_PERSON).withIcon(new QIcon().withName("person"))) + .withChild(qInstance.getTable(TABLE_NAME_PET).withIcon(new QIcon().withName("pets"))) .withChild(qInstance.getTable(TABLE_NAME_CITY).withIcon(new QIcon().withName("location_city"))) .withChild(qInstance.getProcess(PROCESS_NAME_GREET_INTERACTIVE).withIcon(new QIcon().withName("waving_hand"))) .withWidgets(List.of(PersonsByCreateDateBarChart.class.getSimpleName(), QuickSightChartRenderer.class.getSimpleName())) @@ -340,11 +388,62 @@ public class SampleMetaDataProvider QInstanceEnricher.setInferredFieldBackendNames(qTableMetaData); + qTableMetaData.withAssociation(new Association() + .withAssociatedTableName(TABLE_NAME_PET) + .withName("pets") + .withJoinName(QJoinMetaData.makeInferredJoinName(TABLE_NAME_PERSON, TABLE_NAME_PET))); + return (qTableMetaData); } + /******************************************************************************* + ** + *******************************************************************************/ + public static QTableMetaData defineTablePet() + { + QTableMetaData qTableMetaData = new QTableMetaData() + .withName(TABLE_NAME_PET) + .withLabel("Pet") + .withBackendName(RDBMS_BACKEND_NAME) + .withPrimaryKeyField("id") + .withRecordLabelFormat("%s %s") + .withRecordLabelFields("name") + .withField(new QFieldMetaData("id", QFieldType.INTEGER).withIsEditable(false)) + .withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME).withBackendName("create_date").withIsEditable(false)) + .withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME).withBackendName("modify_date").withIsEditable(false)) + .withField(new QFieldMetaData("name", QFieldType.STRING).withBackendName("name").withIsRequired(true)) + .withField(new QFieldMetaData("personId", QFieldType.INTEGER).withBackendName("person_id").withIsRequired(true).withPossibleValueSourceName(TABLE_NAME_PERSON)) + .withField(new QFieldMetaData("speciesId", QFieldType.INTEGER).withBackendName("species_id").withIsRequired(true).withPossibleValueSourceName(PetSpecies.NAME)) + .withField(new QFieldMetaData("birthDate", QFieldType.DATE).withBackendName("birth_date")) + + .withSection(new QFieldSection("identity", "Identity", new QIcon("badge"), Tier.T1, List.of("id", "name"))) + .withSection(new QFieldSection("basicInfo", "Basic Info", new QIcon("dataset"), Tier.T2, List.of("personId", "speciesId", "birthDate"))) + .withSection(new QFieldSection("dates", "Dates", new QIcon("calendar_month"), Tier.T3, List.of("createDate", "modifyDate"))); + + QInstanceEnricher.setInferredFieldBackendNames(qTableMetaData); + + return (qTableMetaData); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + private static QJoinMetaData defineTablePersonJoinPet() + { + return new QJoinMetaData() + .withLeftTable(TABLE_NAME_PERSON) + .withRightTable(TABLE_NAME_PET) + .withInferredName() + .withType(JoinType.ONE_TO_MANY) + .withJoinOn(new JoinOn("id", "personId")); + } + + + /******************************************************************************* ** *******************************************************************************/ @@ -524,6 +623,40 @@ public class SampleMetaDataProvider + /******************************************************************************* + ** + *******************************************************************************/ + public static QBackendMetaData defineUploadArchiveBackend() + { + return new FilesystemBackendMetaData() + .withName(BACKEND_NAME_UPLOAD_ARCHIVE) + .withBasePath("/tmp/" + BACKEND_NAME_UPLOAD_ARCHIVE); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static QTableMetaData defineTableUploadFileArchive() + { + return (new QTableMetaData() + .withName(UPLOAD_FILE_ARCHIVE_TABLE_NAME) + .withBackendName(BACKEND_NAME_UPLOAD_ARCHIVE) + .withPrimaryKeyField("fileName") + // .withSupplementalMetaData(new ApiTableMetaDataContainer()) // empty container means no apis for this table + .withField(new QFieldMetaData("fileName", QFieldType.STRING)) + .withField(new QFieldMetaData("contents", QFieldType.BLOB)) + .withAuditRules(new QAuditRules().withAuditLevel(AuditLevel.NONE)) + .withBackendDetails(new S3TableBackendDetails() + .withCardinality(Cardinality.ONE) + .withFileNameFieldName("fileName") + .withContentsFieldName("contents") + .withBasePath("upload-file-archive"))); + } + + + /******************************************************************************* ** Testing backend step - just sleeps however long you ask it to (or, throws if ** you don't provide a number of seconds to sleep). @@ -625,4 +758,53 @@ public class SampleMetaDataProvider } } + + + /*************************************************************************** + ** + ***************************************************************************/ + public enum PetSpecies implements PossibleValueEnum + { + DOG(1, "Dog"), + CAT(1, "Cat"); + + private final Integer id; + private final String label; + + public static final String NAME = "petSpecies"; + + + + /*************************************************************************** + ** + ***************************************************************************/ + PetSpecies(int id, String label) + { + this.id = id; + this.label = label; + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public Integer getPossibleValueId() + { + return (id); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public String getPossibleValueLabel() + { + return (label); + } + } + } diff --git a/qqq-sample-project/src/test/resources/prime-test-database.sql b/qqq-sample-project/src/main/resources/prime-test-database.sql similarity index 82% rename from qqq-sample-project/src/test/resources/prime-test-database.sql rename to qqq-sample-project/src/main/resources/prime-test-database.sql index 10185156..1f5e6bc9 100644 --- a/qqq-sample-project/src/test/resources/prime-test-database.sql +++ b/qqq-sample-project/src/main/resources/prime-test-database.sql @@ -42,6 +42,27 @@ INSERT INTO person (id, first_name, last_name, birth_date, email, is_employed, a INSERT INTO person (id, first_name, last_name, birth_date, email, is_employed, annual_salary, days_worked) VALUES (4, 'Tyler', 'Samples', NULL, 'tsamples@mmltholdings.com', 1, 950000, 75); INSERT INTO person (id, first_name, last_name, birth_date, email, is_employed, annual_salary, days_worked) VALUES (5, 'Garret', 'Richardson', '1981-01-01', 'grichardson@mmltholdings.com', 0, 1500000, 1); +DROP TABLE IF EXISTS pet; +CREATE TABLE pet +( + id INT AUTO_INCREMENT primary key , + create_date TIMESTAMP DEFAULT now(), + modify_date TIMESTAMP DEFAULT now(), + + name VARCHAR(80) NOT NULL, + species_id INTEGER NOT NULL, + person_id INTEGER NOT NULL, + birth_date DATE +); + +INSERT INTO pet (id, name, species_id, person_id) VALUES (1, 'Charlie', 1, 1); +INSERT INTO pet (id, name, species_id, person_id) VALUES (2, 'Coco', 1, 1); +INSERT INTO pet (id, name, species_id, person_id) VALUES (3, 'Louie', 1, 1); +INSERT INTO pet (id, name, species_id, person_id) VALUES (4, 'Barkley', 1, 1); +INSERT INTO pet (id, name, species_id, person_id) VALUES (5, 'Toby', 1, 2); +INSERT INTO pet (id, name, species_id, person_id) VALUES (6, 'Mae', 2, 3); + + DROP TABLE IF EXISTS carrier; CREATE TABLE carrier (