diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java
new file mode 100644
index 000000000..03c2e9003
--- /dev/null
+++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/CreateTableParser.java
@@ -0,0 +1,137 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.db.sql.parsing;
+
+import com.djrapitops.plan.db.DBType;
+import com.djrapitops.plugin.utilities.Verify;
+
+/**
+ * SqlParser Class for parsing table creation, removal and modification statements.
+ *
+ * @author Rsl1122
+ */
+public class CreateTableParser {
+
+ private final DBType dbType;
+
+ private final StringBuilder columns;
+ private final StringBuilder keyConstraints;
+
+ private StringBuilder columnBuilder;
+ private int columnCount = 0;
+ private int constraintCount = 0;
+
+ private CreateTableParser(DBType dbType, String tableName) {
+ this.dbType = dbType;
+ columns = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
+ keyConstraints = new StringBuilder();
+ }
+
+ public static CreateTableParser create(String tableName, DBType type) {
+ return new CreateTableParser(type, tableName);
+ }
+
+ private void finalizeColumn() {
+ if (columnBuilder != null) {
+ if (columnCount > 0) {
+ columns.append(", ");
+ }
+ columns.append(columnBuilder.toString());
+ columnCount++;
+ columnBuilder = null;
+ }
+ }
+
+ public CreateTableParser column(String column, String type) {
+ finalizeColumn();
+ columnBuilder = new StringBuilder();
+ columnBuilder.append(column).append(" ").append(type);
+ return this;
+ }
+
+ public CreateTableParser primaryKey() {
+ String currentColumn = columnBuilder.substring(0, columnBuilder.indexOf(" "));
+ if (dbType.supportsMySQLQueries()) {
+ notNull();
+ columnBuilder.append(" AUTO_INCREMENT");
+ } else {
+ columnBuilder.append(" PRIMARY KEY");
+ }
+ primaryKey(currentColumn);
+ return this;
+ }
+
+ public CreateTableParser notNull() {
+ columnBuilder.append(" NOT NULL");
+ return this;
+ }
+
+ public CreateTableParser unique() {
+ columnBuilder.append(" UNIQUE");
+ return this;
+ }
+
+ public CreateTableParser defaultValue(boolean value) {
+ return defaultValue(value ? "1" : "0");
+ }
+
+ public CreateTableParser defaultValue(String value) {
+ columnBuilder.append(" DEFAULT ").append(value);
+ return this;
+ }
+
+ public CreateTableParser foreignKey(String column, String referencedTable, String referencedColumn) {
+ finalizeColumn();
+ if (constraintCount > 0) {
+ keyConstraints.append(", ");
+ }
+ keyConstraints.append("FOREIGN KEY(")
+ .append(column)
+ .append(") REFERENCES ")
+ .append(referencedTable)
+ .append("(")
+ .append(referencedColumn)
+ .append(")");
+ constraintCount++;
+ return this;
+ }
+
+ private void primaryKey(String column) {
+ finalizeColumn();
+ if (constraintCount > 0) {
+ keyConstraints.append(", ");
+ }
+ keyConstraints.append("PRIMARY KEY (").append(column).append(")");
+ constraintCount++;
+ }
+
+ public String build() {
+ return toString();
+ }
+
+ @Override
+ public String toString() {
+ finalizeColumn();
+
+ Verify.isTrue(columnCount > 0, () -> new IllegalStateException("No columns specified for statement '" + columns.toString() + "..'"));
+ if (constraintCount > 0) {
+ return columns.toString() + ", " + keyConstraints.toString() + ')';
+ } else {
+ return columns.toString() + ')';
+ }
+ }
+}
diff --git a/Plan/common/src/test/java/com/djrapitops/plan/db/sql/parsing/CreateTableParserTest.java b/Plan/common/src/test/java/com/djrapitops/plan/db/sql/parsing/CreateTableParserTest.java
new file mode 100644
index 000000000..fa99d7299
--- /dev/null
+++ b/Plan/common/src/test/java/com/djrapitops/plan/db/sql/parsing/CreateTableParserTest.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of Player Analytics (Plan).
+ *
+ * Plan is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License v3 as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Plan 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Plan. If not, see .
+ */
+package com.djrapitops.plan.db.sql.parsing;
+
+import com.djrapitops.plan.db.DBType;
+import com.djrapitops.plan.db.sql.tables.ServerTable;
+import org.junit.jupiter.api.Test;
+import org.junit.platform.runner.JUnitPlatform;
+import org.junit.runner.RunWith;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Tests for {@link CreateTableParser}.
+ *
+ * @author Rsl1122
+ */
+@RunWith(JUnitPlatform.class)
+class CreateTableParserTest {
+
+ @Test
+ void createsSameTablesAsOldParser() {
+ String expected = "CREATE TABLE IF NOT EXISTS plan_servers (id integer NOT NULL AUTO_INCREMENT, uuid varchar(36) NOT NULL UNIQUE, name varchar(100), web_address varchar(100), is_installed boolean NOT NULL DEFAULT 1, max_players integer NOT NULL DEFAULT -1, PRIMARY KEY (id))";
+ String result = CreateTableParser.create(ServerTable.TABLE_NAME, DBType.MYSQL)
+ .column(ServerTable.Col.SERVER_ID.get(), Sql.INT)
+ .primaryKey()
+ .column(ServerTable.Col.SERVER_UUID.get(), Sql.varchar(36)).notNull().unique()
+ .column(ServerTable.Col.NAME.get(), Sql.varchar(100))
+ .column(ServerTable.Col.WEBSERVER_ADDRESS.get(), Sql.varchar(100))
+ .column(ServerTable.Col.INSTALLED.get(), Sql.BOOL).notNull().defaultValue(true)
+ .column(ServerTable.Col.MAX_PLAYERS.get(), Sql.INT).notNull().defaultValue("-1")
+ .toString();
+ assertEquals(expected, result);
+ }
+
+}
\ No newline at end of file