From 456ed9b8c3ad0128719a538fad582e19e10cc418 Mon Sep 17 00:00:00 2001 From: Anastasiia Sergienko Date: Fri, 5 Apr 2019 14:56:46 +0200 Subject: [PATCH] #43: implemented create schema logic --- .../com/exasol/sql/SqlStatementVisitor.java | 8 --- .../java/com/exasol/sql/StatementFactory.java | 11 ++++ src/main/java/com/exasol/sql/Table.java | 15 +++++- src/main/java/com/exasol/sql/ddl/Schema.java | 36 +++++++++++++ .../exasol/sql/ddl/create/CreateSchema.java | 37 +++++++++++++ .../sql/ddl/create/CreateSchemaFragment.java | 15 ++++++ .../sql/ddl/create/CreateSchemaVisitor.java | 9 ++++ .../exasol/sql/ddl/create/CreateTable.java | 18 +++++-- .../sql/ddl/create/CreateTableVisitor.java | 6 ++- .../rendering/CreateSchemaRenderer.java | 52 +++++++++++++++++++ .../exasol/sql/ddl/drop/DropTableVisitor.java | 6 ++- .../SqlFragmentRenderResultMatcher.java | 7 ++- .../sql/ddl/create/TestCreateSchema.java | 23 ++++++++ .../rendering/TestCreateSchemaRenderer.java | 26 ++++++++++ .../rendering/TestCreateSchemaRendering.java | 25 +++++++++ .../rendering/TestCreateTableRenderer.java | 2 +- .../drop/rendering/TestDropTableRenderer.java | 2 +- 17 files changed, 276 insertions(+), 22 deletions(-) delete mode 100644 src/main/java/com/exasol/sql/SqlStatementVisitor.java create mode 100644 src/main/java/com/exasol/sql/ddl/Schema.java create mode 100644 src/main/java/com/exasol/sql/ddl/create/CreateSchema.java create mode 100644 src/main/java/com/exasol/sql/ddl/create/CreateSchemaFragment.java create mode 100644 src/main/java/com/exasol/sql/ddl/create/CreateSchemaVisitor.java create mode 100644 src/main/java/com/exasol/sql/ddl/create/rendering/CreateSchemaRenderer.java create mode 100644 src/test/java/com/exasol/sql/ddl/create/TestCreateSchema.java create mode 100644 src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRenderer.java create mode 100644 src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRendering.java diff --git a/src/main/java/com/exasol/sql/SqlStatementVisitor.java b/src/main/java/com/exasol/sql/SqlStatementVisitor.java deleted file mode 100644 index 2b35ec4a..00000000 --- a/src/main/java/com/exasol/sql/SqlStatementVisitor.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.exasol.sql; - -/** - * This interface represents a visitor for SQL statement fragments. - */ -public interface SqlStatementVisitor { - public void visit(Table table); -} \ No newline at end of file diff --git a/src/main/java/com/exasol/sql/StatementFactory.java b/src/main/java/com/exasol/sql/StatementFactory.java index 490f43a2..b648138c 100644 --- a/src/main/java/com/exasol/sql/StatementFactory.java +++ b/src/main/java/com/exasol/sql/StatementFactory.java @@ -1,5 +1,6 @@ package com.exasol.sql; +import com.exasol.sql.ddl.create.CreateSchema; import com.exasol.sql.ddl.create.CreateTable; import com.exasol.sql.ddl.drop.DropTable; import com.exasol.sql.dml.Insert; @@ -56,6 +57,16 @@ public CreateTable createTable(final String tableName) { return new CreateTable(tableName); } + /** + * Create a {@link CreateSchema} statement + * + * @param schemaName name of the schema to create + * @return a new instance of a {@link CreateSchema} statement + */ + public CreateSchema createSchema(String schemaName) { + return new CreateSchema(schemaName); + } + /** * Create a {@link DropTable} statement * diff --git a/src/main/java/com/exasol/sql/Table.java b/src/main/java/com/exasol/sql/Table.java index 121f0a3d..985b11e4 100644 --- a/src/main/java/com/exasol/sql/Table.java +++ b/src/main/java/com/exasol/sql/Table.java @@ -1,5 +1,8 @@ package com.exasol.sql; +import com.exasol.sql.ddl.create.CreateTableVisitor; +import com.exasol.sql.ddl.drop.DropTableVisitor; + import java.util.Optional; /** @@ -26,7 +29,7 @@ public Table(final Fragment root, final String name) { * * @param root SQL statement this table belongs to * @param name table name - * @param as table alias + * @param as table alias */ public Table(final Fragment root, final String name, final String as) { super(root); @@ -52,7 +55,15 @@ public Optional getAs() { return this.as; } - public void accept(final SqlStatementVisitor visitor) { + public void accept(final TableValuesVisitor visitor) { + visitor.visit(this); + } + + public void accept(final CreateTableVisitor visitor) { + visitor.visit(this); + } + + public void accept(final DropTableVisitor visitor) { visitor.visit(this); } } \ No newline at end of file diff --git a/src/main/java/com/exasol/sql/ddl/Schema.java b/src/main/java/com/exasol/sql/ddl/Schema.java new file mode 100644 index 00000000..e3192553 --- /dev/null +++ b/src/main/java/com/exasol/sql/ddl/Schema.java @@ -0,0 +1,36 @@ +package com.exasol.sql.ddl; + +import com.exasol.sql.AbstractFragment; +import com.exasol.sql.Fragment; +import com.exasol.sql.ddl.create.CreateSchemaVisitor; + +/** + * This class represents a {@link Schema} in an SQL Statement + */ +public class Schema extends AbstractFragment { + private String name; + + /** + * Create a new {@link Schema} + * + * @param root SQL statement this schema belongs to + * @param schemaName schema name + */ + public Schema(Fragment root, String schemaName) { + super(root); + this.name = schemaName; + } + + /** + * Get a schema name + * + * @return schema name + */ + public String getName() { + return name; + } + + public void accept(CreateSchemaVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateSchema.java b/src/main/java/com/exasol/sql/ddl/create/CreateSchema.java new file mode 100644 index 00000000..d45e786e --- /dev/null +++ b/src/main/java/com/exasol/sql/ddl/create/CreateSchema.java @@ -0,0 +1,37 @@ +package com.exasol.sql.ddl.create; + +import com.exasol.sql.AbstractFragment; +import com.exasol.sql.SqlStatement; +import com.exasol.sql.ddl.Schema; + +/** + * This class implements an SQL {@link CreateSchema} statement + */ +public class CreateSchema extends AbstractFragment implements SqlStatement, CreateSchemaFragment { + private Schema schema; + + /** + * Create a new instance of an {@link CreateSchema} statement + * + * @param schemaName name of the table to create + */ + public CreateSchema(final String schemaName) { + super(null); + this.schema = new Schema(this, schemaName); + } + + /** + * Get a schema name + * + * @return schema name + */ + public String getSchemaName() { + return schema.getName(); + } + + @Override + public void accept(CreateSchemaVisitor visitor) { + visitor.visit(this); + this.schema.accept(visitor); + } +} \ No newline at end of file diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateSchemaFragment.java b/src/main/java/com/exasol/sql/ddl/create/CreateSchemaFragment.java new file mode 100644 index 00000000..006f2d31 --- /dev/null +++ b/src/main/java/com/exasol/sql/ddl/create/CreateSchemaFragment.java @@ -0,0 +1,15 @@ +package com.exasol.sql.ddl.create; + +import com.exasol.sql.Fragment; + +/** + * This is the common interface for all fragments of a CREATE SCHEMA statement. + */ +public interface CreateSchemaFragment extends Fragment { + /** + * Accept a visitor (e.g. a renderer or validator) + * + * @param visitor visitor to accept + */ + public void accept(CreateSchemaVisitor visitor); +} diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateSchemaVisitor.java b/src/main/java/com/exasol/sql/ddl/create/CreateSchemaVisitor.java new file mode 100644 index 00000000..3962f24c --- /dev/null +++ b/src/main/java/com/exasol/sql/ddl/create/CreateSchemaVisitor.java @@ -0,0 +1,9 @@ +package com.exasol.sql.ddl.create; + +import com.exasol.sql.ddl.Schema; + +public interface CreateSchemaVisitor { + public void visit(CreateSchema createSchema); + + public void visit(Schema schema); +} diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateTable.java b/src/main/java/com/exasol/sql/ddl/create/CreateTable.java index d8c84ff1..180449c6 100644 --- a/src/main/java/com/exasol/sql/ddl/create/CreateTable.java +++ b/src/main/java/com/exasol/sql/ddl/create/CreateTable.java @@ -2,9 +2,7 @@ import com.exasol.datatype.type.Boolean; import com.exasol.datatype.type.*; -import com.exasol.sql.AbstractFragment; -import com.exasol.sql.SqlStatement; -import com.exasol.sql.Table; +import com.exasol.sql.*; /** * This class implements an SQL {@link CreateTable} statement @@ -151,11 +149,21 @@ public synchronized CreateTable intervalYearToMonthColumn(final String columnNam return this; } - protected String getTableName() { + /** + * Get a table name + * + * @return table name + */ + public String getTableName() { return this.table.getName(); } - protected ColumnsDefinition getColumns() { + /** + * Get columns of a table + * + * @return columns + */ + public ColumnsDefinition getColumns() { return this.columnsDefinition; } diff --git a/src/main/java/com/exasol/sql/ddl/create/CreateTableVisitor.java b/src/main/java/com/exasol/sql/ddl/create/CreateTableVisitor.java index 741dd815..e46b2cc6 100644 --- a/src/main/java/com/exasol/sql/ddl/create/CreateTableVisitor.java +++ b/src/main/java/com/exasol/sql/ddl/create/CreateTableVisitor.java @@ -2,9 +2,11 @@ import com.exasol.datatype.type.Boolean; import com.exasol.datatype.type.*; -import com.exasol.sql.SqlStatementVisitor; +import com.exasol.sql.Table; + +public interface CreateTableVisitor { + public void visit(final Table table); -public interface CreateTableVisitor extends SqlStatementVisitor { public void visit(final CreateTable createTable); public void visit(final Column column); diff --git a/src/main/java/com/exasol/sql/ddl/create/rendering/CreateSchemaRenderer.java b/src/main/java/com/exasol/sql/ddl/create/rendering/CreateSchemaRenderer.java new file mode 100644 index 00000000..cbdbbecf --- /dev/null +++ b/src/main/java/com/exasol/sql/ddl/create/rendering/CreateSchemaRenderer.java @@ -0,0 +1,52 @@ +package com.exasol.sql.ddl.create.rendering; + +import com.exasol.sql.ddl.Schema; +import com.exasol.sql.ddl.create.CreateSchema; +import com.exasol.sql.ddl.create.CreateSchemaVisitor; +import com.exasol.sql.rendering.AbstractFragmentRenderer; +import com.exasol.sql.rendering.StringRendererConfig; + +/** + * The {@link CreateSchemaRenderer} turns SQL statement structures in to SQL strings. + */ +public class CreateSchemaRenderer extends AbstractFragmentRenderer implements CreateSchemaVisitor { + /** + * Create a new {@link CreateSchemaRenderer} with custom render settings. + * + * @param config render configuration settings + */ + public CreateSchemaRenderer(final StringRendererConfig config) { + super(config); + } + + /** + * Create an {@link CreateSchemaRenderer} using the default renderer configuration + * + * @return insert renderer + */ + public static CreateSchemaRenderer create() { + return new CreateSchemaRenderer(StringRendererConfig.createDefault()); + } + + /** + * Create an {@link CreateSchemaRenderer} + * + * @param config renderer configuration + * @return create schema renderer + */ + public static CreateSchemaRenderer create(final StringRendererConfig config) { + return new CreateSchemaRenderer(config); + } + + @Override + public void visit(CreateSchema createSchema) { + appendKeyWord("CREATE SCHEMA "); + setLastVisited(createSchema); + } + + @Override + public void visit(Schema schema) { + appendAutoQuoted(schema.getName()); + setLastVisited(schema); + } +} diff --git a/src/main/java/com/exasol/sql/ddl/drop/DropTableVisitor.java b/src/main/java/com/exasol/sql/ddl/drop/DropTableVisitor.java index 17b583d3..79d2d8e9 100644 --- a/src/main/java/com/exasol/sql/ddl/drop/DropTableVisitor.java +++ b/src/main/java/com/exasol/sql/ddl/drop/DropTableVisitor.java @@ -1,8 +1,10 @@ package com.exasol.sql.ddl.drop; -import com.exasol.sql.SqlStatementVisitor; +import com.exasol.sql.Table; + +public interface DropTableVisitor { + public void visit(Table table); -public interface DropTableVisitor extends SqlStatementVisitor { public void visit(DropTable dropTable); public void visit(CascadeConstraints cascadeConstraints); diff --git a/src/test/java/com/exasol/hamcrest/SqlFragmentRenderResultMatcher.java b/src/test/java/com/exasol/hamcrest/SqlFragmentRenderResultMatcher.java index 403cb5a7..c954cf7a 100644 --- a/src/test/java/com/exasol/hamcrest/SqlFragmentRenderResultMatcher.java +++ b/src/test/java/com/exasol/hamcrest/SqlFragmentRenderResultMatcher.java @@ -1,6 +1,7 @@ package com.exasol.hamcrest; -import com.exasol.sql.ddl.create.CreateTableFragment; +import com.exasol.sql.ddl.create.*; +import com.exasol.sql.ddl.create.rendering.CreateSchemaRenderer; import com.exasol.sql.ddl.create.rendering.CreateTableRenderer; import com.exasol.sql.ddl.drop.DropTableFragment; import com.exasol.sql.ddl.drop.rendering.DropTableRenderer; @@ -54,6 +55,10 @@ public boolean matchesSafely(final Fragment fragment) { final DropTableRenderer renderer = new DropTableRenderer(this.config); ((DropTableFragment) root).accept(renderer); this.renderedText = renderer.render(); + } else if (root instanceof CreateSchemaFragment) { + final CreateSchemaRenderer renderer = new CreateSchemaRenderer(this.config); + ((CreateSchemaFragment) root).accept(renderer); + this.renderedText = renderer.render(); } else { throw new UnsupportedOperationException( "Don't know how to render fragment of type\"" + root.getClass().getName() + "\"."); diff --git a/src/test/java/com/exasol/sql/ddl/create/TestCreateSchema.java b/src/test/java/com/exasol/sql/ddl/create/TestCreateSchema.java new file mode 100644 index 00000000..c95e1fee --- /dev/null +++ b/src/test/java/com/exasol/sql/ddl/create/TestCreateSchema.java @@ -0,0 +1,23 @@ +package com.exasol.sql.ddl.create; + +import com.exasol.sql.StatementFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +class TestCreateSchema { + private static final String TEST_SCHEMA_NAME = "test schema name"; + private CreateSchema createSchema; + + @BeforeEach + void setUp() { + createSchema = StatementFactory.getInstance().createSchema(TEST_SCHEMA_NAME); + } + + @Test + void getTableName() { + assertThat(this.createSchema.getSchemaName(), equalTo(TEST_SCHEMA_NAME)); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRenderer.java b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRenderer.java new file mode 100644 index 00000000..f6ce5fc2 --- /dev/null +++ b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRenderer.java @@ -0,0 +1,26 @@ +package com.exasol.sql.ddl.create.rendering; + +import com.exasol.sql.StatementFactory; +import com.exasol.sql.ddl.create.CreateSchema; +import com.exasol.sql.rendering.StringRendererConfig; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.startsWith; + +class TestCreateSchemaRenderer { + @Test + void testCreateWithDefaultConfig() { + assertThat(CreateSchemaRenderer.create(), instanceOf(CreateSchemaRenderer.class)); + } + + @Test + void testCreateWithConfig() { + final StringRendererConfig config = StringRendererConfig.builder().lowerCase(true).build(); + final CreateSchemaRenderer renderer = CreateSchemaRenderer.create(config); + final CreateSchema createSchema = StatementFactory.getInstance().createSchema("test name"); + createSchema.accept(renderer); + assertThat(renderer.render(), startsWith("create schema")); + } +} diff --git a/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRendering.java b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRendering.java new file mode 100644 index 00000000..28f00864 --- /dev/null +++ b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateSchemaRendering.java @@ -0,0 +1,25 @@ +package com.exasol.sql.ddl.create.rendering; + +import com.exasol.sql.StatementFactory; +import com.exasol.sql.ddl.create.CreateSchema; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo; +import static org.hamcrest.MatcherAssert.assertThat; + +class TestCreateSchemaRendering { + private static final String SCHEMA_NAME = "testName"; + private CreateSchema createSchema; + + @BeforeEach + void beforeEach() { + this.createSchema = StatementFactory.getInstance().createSchema(SCHEMA_NAME); + } + + + @Test + void testCreateSchema() { + assertThat(this.createSchema, rendersTo("CREATE SCHEMA testName")); + } +} diff --git a/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateTableRenderer.java b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateTableRenderer.java index 4b08ed87..c0a69acc 100644 --- a/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateTableRenderer.java +++ b/src/test/java/com/exasol/sql/ddl/create/rendering/TestCreateTableRenderer.java @@ -21,6 +21,6 @@ void testCreateWithConfig() { final CreateTableRenderer renderer = CreateTableRenderer.create(config); final CreateTable createTable = StatementFactory.getInstance().createTable("test name"); createTable.accept(renderer); - assertThat(renderer.render(), startsWith("create")); + assertThat(renderer.render(), startsWith("create table")); } } diff --git a/src/test/java/com/exasol/sql/ddl/drop/rendering/TestDropTableRenderer.java b/src/test/java/com/exasol/sql/ddl/drop/rendering/TestDropTableRenderer.java index 491d87b2..009f26b4 100644 --- a/src/test/java/com/exasol/sql/ddl/drop/rendering/TestDropTableRenderer.java +++ b/src/test/java/com/exasol/sql/ddl/drop/rendering/TestDropTableRenderer.java @@ -21,6 +21,6 @@ void testCreateWithConfig() { final DropTableRenderer renderer = DropTableRenderer.create(config); final DropTable dropTable = StatementFactory.getInstance().dropTable("test name"); dropTable.accept(renderer); - assertThat(renderer.render(), startsWith("drop")); + assertThat(renderer.render(), startsWith("drop table")); } }