diff --git a/.gitignore b/.gitignore
index a1c2a238..ae1ac990 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,9 @@
+target/
+*.iml
+
+#############################################
+## Original contents from github template: ##
+#############################################
# Compiled class file
*.class
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 00000000..fadf2cda
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 00000000..5c735af1
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,139 @@
+
+
+ 4.0.0
+
+ com.kingsrook.qqq
+ qqq-backend-module-rdbms
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 17
+ 17
+ true
+ true
+
+
+
+
+
+ com.kingsrook.qqq
+ qqq-backend-core
+ 0.0-SNAPSHOT
+
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.26
+
+
+ com.h2database
+ h2
+ 1.4.197
+ test
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.1.2
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.14.1
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.14.1
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.1
+ test
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ -Xlint:unchecked
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M5
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.1.2
+
+
+ com.puppycrawl.tools
+ checkstyle
+ 9.0
+
+
+
+
+ validate
+ validate
+
+ checkstyle.xml
+
+ UTF-8
+ true
+ false
+ true
+ warning
+ **/target/generated-sources/*.*
+
+
+
+ check
+
+
+
+
+
+
+
+
+
+ github
+ GitHub kingsrook Maven Packages
+ https://maven.pkg.github.com/Kingsrook/qqq-maven-registry
+
+
+
+
+
+ github
+ GitHub kingsrook Maven Packages
+ https://maven.pkg.github.com/Kingsrook/qqq-maven-registry
+
+
+
+
diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMBackendMetaData.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMBackendMetaData.java
new file mode 100644
index 00000000..7d624cc0
--- /dev/null
+++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMBackendMetaData.java
@@ -0,0 +1,83 @@
+package com.kingsrook.qqq.backend.module.rdbms;
+
+
+import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class RDBSMBackendMetaData extends QBackendMetaData
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public RDBSMBackendMetaData(QBackendMetaData source)
+ {
+ super();
+ setName(source.getName());
+ setValues(source.getValues());
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getVendor()
+ {
+ return getValue("vendor");
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getHostName()
+ {
+ return getValue("hostName");
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getPort()
+ {
+ return getValue("port");
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getDatabaseName()
+ {
+ return getValue("databaseName");
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getUsername()
+ {
+ return getValue("username");
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public String getPassword()
+ {
+ return getValue("password");
+ }
+
+}
diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMModule.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMModule.java
new file mode 100644
index 00000000..564ba151
--- /dev/null
+++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBSMModule.java
@@ -0,0 +1,35 @@
+package com.kingsrook.qqq.backend.module.rdbms;
+
+
+import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface;
+import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
+import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface;
+import com.kingsrook.qqq.backend.module.rdbms.actions.RDBMSInsertAction;
+import com.kingsrook.qqq.backend.module.rdbms.actions.RDBMSQueryAction;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class RDBSMModule implements QModuleInterface
+{
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public QueryInterface getQueryInterface()
+ {
+ return new RDBMSQueryAction();
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Override
+ public InsertInterface getInsertInterface()
+ {
+ return (new RDBMSInsertAction());
+ }
+}
diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java
new file mode 100644
index 00000000..d66034a9
--- /dev/null
+++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java
@@ -0,0 +1,25 @@
+package com.kingsrook.qqq.backend.module.rdbms.actions;
+
+
+import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public abstract class AbstractRDBMSAction
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ protected String getColumnName(QFieldMetaData field)
+ {
+ if(field.getBackendName() != null)
+ {
+ return (field.getBackendName());
+ }
+ return (field.getName());
+ }
+
+}
diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java
new file mode 100644
index 00000000..63f6727d
--- /dev/null
+++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java
@@ -0,0 +1,168 @@
+package com.kingsrook.qqq.backend.module.rdbms.actions;
+
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.InsertRequest;
+import com.kingsrook.qqq.backend.core.model.actions.InsertResult;
+import com.kingsrook.qqq.backend.core.model.actions.QFilterCriteria;
+import com.kingsrook.qqq.backend.core.model.actions.QFilterOrderBy;
+import com.kingsrook.qqq.backend.core.model.data.QRecord;
+import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus;
+import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
+import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface;
+import com.kingsrook.qqq.backend.module.rdbms.RDBSMBackendMetaData;
+import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager;
+import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInterface
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public InsertResult execute(InsertRequest insertRequest) throws QException
+ {
+ try
+ {
+ InsertResult rs = new InsertResult();
+ QTableMetaData table = insertRequest.getTable();
+
+ List insertableFields = table.getFields().stream()
+ .filter(field -> !field.getName().equals("id")) // todo - intent here is to avoid non-insertable fields.
+ .toList();
+
+ String columns = insertableFields.stream()
+ .map(this::getColumnName)
+ .collect(Collectors.joining(", "));
+ String questionMarks = insertableFields.stream()
+ .map(x -> "?")
+ .collect(Collectors.joining(", "));
+
+ String tableName = table.getName();
+ StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append("(").append(columns).append(") VALUES");
+ List