Skip to content
Browse files

Added DDL parsing example

  • Loading branch information...
1 parent fa46e0f commit dc69252c8e0a810fad99f39fe321546eac2280f7 @rhauch rhauch committed May 26, 2011
View
29 .gitignore
@@ -1 +1,28 @@
-target
+# ignore Maven generated target folders
+target
+
+# ignore eclipse files and folders
+.project
+.classpath
+.settings
+.metadata
+.scala_dependencies
+.externalToolBuilders
+/.metadata
+/RemoteSystemsTempFiles
+
+# ignore IDEA files
+*.iml
+*.ipr
+*.iws
+.idea
+atlassian-ide-plugin.xml
+
+# Compiled python files
+*.pyc
+
+# REST client module bin folder
+/tools/org.modeshape.eclipse.jcr.rest.client/bin
+
+# Presentation Keynote files
+/docs/presentations/*.key
View
51 modeshape-ddl-parser-example/README.md
@@ -0,0 +1,51 @@
+# ModeShape DDL Parsing Example
+
+The [ModeShape DDL Sequencer library](http://docs.jboss.org/modeshape/latest/manuals/reference/html_single/reference-guide-en.html#ddl-file-sequencer)
+contains a DDL parser capable of parsing many common DDL statements conforming to SQL-92, MySQL, Oracle, PostgreSQL,
+Sybase, DB2, and Derby. The sequencer uses this parser to build an internal AST representation of the DDL statements, and then the sequencer
+turns that AST representation into a graph representation (which ModeShape then persists as part of the sequencing service).
+
+However, this DDL parser can be used on its own, as long as one understands the parsers limitations and is willing to process the very generic AST representation
+for DDL statements that can vary wildly.
+
+It is also important to understand that DDL statements actually describe operations to be performed against a database schema.
+Many of us are familiar with DDL that creates a set of tables and views, and transforming such statements into a model of a database
+is relatively straightforward. But this transformation becomes more complicated when the DDL contain ALTER, DROP, ADD COLUMN and other such
+statements.
+
+This example shows how to use the DDL parser to produce a simplistic model of a database schema. It generally works against the more common
+create-type DDL statements, although some ALTER statements are supported. The example also does not process primary keys, indexes, foreign keys,
+and other more detailed statements; these are left to the reader, but we'd welcome pull-requests with improvements or changes.
+
+# Building
+
+This project is self-contained and can be built at the top level of your local clone of the Git repository,
+or by simply building this project using Maven 3:
+
+ $ mvn clean install
+
+This will compile the code and run the unit tests. Note this example does not currently have a `main` method. It is intended for you to play
+with the code, and to turn on printing in the parser for more verbose output. Try adding your own DDL files and looking at the output,
+and then use the example to help use this DDL parser in your own applications.
+
+See [this ModeShape community article](http://community.jboss.org/wiki/ModeShapeandMaven) for help on how to install Maven 3.
+
+# The ModeShape project
+
+ModeShape is an open source implementation of the JCR 2.0 ([JSR-283](http://www.jcp.org/en/jsr/detail?id=283])) specification and standard API.
+To your applications, ModeShape looks and behaves like a regular JCR repository. Applications can search, query, navigate, change, version, listen for changes, etc.
+But ModeShape can store that content in a variety of back-end stores (including relational databases, Infinispan data grids, JBoss Cache, etc.), or it can
+access and update existing content from *other* kinds of systems (including file systems, SVN repositories, JDBC database metadata, and other JCR repositories).
+ModeShape's connector architecture means that you can write custom connectors to access any kind of system. And ModeShape can even federate multiple back-end systems
+into a single, unified virtual repository.
+
+For more information on ModeShape, including getting started guides, reference guides, and downloadable binaries, visit the project's website at [http://www.modeshape.org]()
+or follow us on our [blog](http://modeshape.wordpress.org) or on [Twitter](http://twitter.com/modeshape). Or hop into our [IRC chat room](http://www.jboss.org/modeshape/chat)
+and talk our community of contributors and users.
+
+The official Git repository for the project is also on GitHub at [http://github.com/ModeShape/modeshape]().
+
+# Need help?
+
+ModeShape is open source software with a dedicated community. If you have any questions or problems, post a question in our
+[user forum](http://community.jboss.org/en/modeshape) or hop into our [IRC chat room](http://www.jboss.org/modeshape/chat) and talk our community of contributors and users.
View
180 modeshape-ddl-parser-example/pom.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.modeshape.example</groupId>
+ <artifactId>modeshape-ddl-parser-example</artifactId>
+ <packaging>jar</packaging>
+ <name>ModeShape DDL Parser Example</name>
+ <description>A simple demo application that parses DDL using the ModeShape DDL sequencer library.</description>
+ <version>1.0-SNAPSHOT</version>
+ <properties>
+ <!-- Instruct the build to use only UTF-8 encoding for source code -->
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <!--
+ Global dependency version information
+ -->
+ <modeshape.version>2.5.0.Final</modeshape.version>
+ <slf4j.api.version>1.5.11</slf4j.api.version>
+ <slf4j.log4j.version>1.5.11</slf4j.log4j.version>
+ <log4j.version>1.2.16</log4j.version>
+ <junit.version>4.8.2</junit.version>
+ <!--
+ Maven plugin versions
+ -->
+ <maven.surefire.report.plugin.version>2.4.3</maven.surefire.report.plugin.version>
+ <maven.surefire.plugin.version>2.7.1</maven.surefire.plugin.version>
+ <maven.assembly.plugin.version>2.2</maven.assembly.plugin.version>
+ <maven.install.plugin.version>2.3.1</maven.install.plugin.version>
+ <maven.jar.plugin.version>2.3.1</maven.jar.plugin.version>
+ <maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version>
+ <maven.source.plugin.version>2.1.2</maven.source.plugin.version>
+ <maven.resources.plugin.version>2.4.3</maven.resources.plugin.version>
+ </properties>
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <!-- Specify the compiler options and settings -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven.compiler.plugin.version}</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ <showDeprecation>false</showDeprecation>
+ <showWarnings>false</showWarnings>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${maven.surefire.plugin.version}</version>
+ <configuration>
+ <includes>
+ <include>**/*TestCase.java</include>
+ <include>**/*Test.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <!-- Produce source jars during the 'verify' phase -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven.source.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ Build a test-jar for each project, so that src/test/* resources and
+ classes can be used in other projects. Also customize how the jar
+ files are assembled.
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven.jar.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>test-jar</id>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>${maven.resources.plugin.version}</version>
+ <configuration>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <!-- DDL sequencer and required ModeShape libraries -->
+ <dependency>
+ <groupId>org.modeshape</groupId>
+ <artifactId>modeshape-sequencer-ddl</artifactId>
+ <version>${modeshape.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.modeshape</groupId>
+ <artifactId>modeshape-graph</artifactId>
+ <version>${modeshape.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.modeshape</groupId>
+ <artifactId>modeshape-common</artifactId>
+ <version>${modeshape.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <!-- Logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.api.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.log4j.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${log4j.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ <!-- Testing (note the scope) -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <repositories>
+ <repository>
+ <id>JBoss-Releases</id>
+ <url>https://repository.jboss.org/nexus/content/repositories/releases/</url>
+ </repository>
+ </repositories>
+</project>
View
529 modeshape-ddl-parser-example/src/main/java/org/modeshape/example/ddl/Parser.java
@@ -0,0 +1,529 @@
+package org.modeshape.example.ddl;
+
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_LENGTH;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_NAME;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_PRECISION;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DATATYPE_SCALE;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DDL_EXPRESSION;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.DEFAULT_VALUE;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_ADD_COLUMN_DEFINITION;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_ALTER_COLUMN_DEFINITION;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_ALTER_TABLE_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_COLUMN_DEFINITION;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_CREATE_SCHEMA_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_CREATE_TABLE_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_CREATE_VIEW_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_SCHEMA_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_TABLE_STATEMENT;
+import static org.modeshape.sequencer.ddl.StandardDdlLexicon.TYPE_DROP_VIEW_STATEMENT;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.modeshape.graph.ExecutionContext;
+import org.modeshape.graph.JcrLexicon;
+import org.modeshape.graph.property.Name;
+import org.modeshape.graph.property.NamespaceRegistry;
+import org.modeshape.graph.property.Property;
+import org.modeshape.sequencer.ddl.DdlParsers;
+import org.modeshape.sequencer.ddl.StandardDdlLexicon;
+import org.modeshape.sequencer.ddl.node.AstNode;
+
+/**
+ * A simple example application that demonstrates how to parse DDL files to create an Abstract Syntax Tree (AST) as a ModeShape
+ * graph and to then post-processes that graph.
+ * <p>
+ * The {@link #parse(File)} method returns a {@link Database} object that contains a final representation of the structure of an
+ * empty database after the supplied (simple) schema is applied. After all, DDL statements are actually operations against a
+ * database, so a DDL file with some statements (like "DROP TABLE foo") don't make sense when applied to an empty database.
+ * </p>
+ * <p>
+ * However, this example works really well when processing DDL statements that create tables, views, and schemas.
+ * </p>
+ * <p>
+ * Note: this example does not process all of the available DDL statements, so many statements (e.g., foreign keys, primary keys,
+ * etc.) are ignored. Support for these are left to the reader. The actual structure of the files is described by the following
+ * JCR CND node type definition files contained within the "modeshape-sequencer-ddl" library:
+ * <ul>
+ * <li>org.modeshape.sequencer.ddl.StandardDdl.cnd</li>
+ * <li>org.modeshape.sequencer.ddl.dialect.derby.DerbyDdl.cnd</li>
+ * <li>org.modeshape.sequencer.ddl.dialect.oracle.OracleDdl.cnd</li>
+ * <li>org.modeshape.sequencer.ddl.dialect.postgres.PostgresDdl.cnd</li>
+ * </ul>
+ * </p>
+ */
+public class Parser {
+
+ // public static void main( String[] argv ) {
+ // // Process the arguments ...
+ // String filename = null;
+ // for (String arg : argv) {
+ // // First non-flag parameter is the filename ...
+ // if (filename == null) filename = arg;
+ // }
+ //
+ // // Figure out if the arguments are valid ...
+ // if (filename == null) {
+ // printUsage(System.out);
+ // System.exit(1);
+ // }
+ // File file = new File(filename);
+ // if (!file.exists()) printError(-1, "The file \"" + filename + "\" does not exist.");
+ // if (!file.isFile()) printError(-2, "File could not be found at \"" + file + "\"");
+ // if (!file.canRead()) printError(-3, "Unable to read file \"" + filename + "\".");
+ //
+ // // Now parse the file ...
+ // try {
+ // Parser parser = new Parser();
+ // parser.parse(file);
+ // } catch (Throwable t) {
+ // printError(-10, t.getMessage());
+ // }
+ // }
+ //
+ // protected static void printError( int exitCode,
+ // String message ) {
+ // System.err.println("Error: " + message);
+ // System.err.println();
+ // printUsage(System.out);
+ // System.exit(exitCode);
+ // }
+ //
+ // protected static void printUsage( PrintStream stream ) {
+ // stream.println("Usage: " + Parser.class.getCanonicalName() + " filename");
+ // stream.println();
+ // stream.println(" where");
+ // stream.println(" filename is the name of the DDL file to be parsed");
+ // stream.println();
+ // }
+
+ protected static String readFile( File file ) throws IOException {
+ StringBuffer fileData = new StringBuffer(1000);
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ try {
+ char[] buf = new char[1024];
+ int numRead = 0;
+ while ((numRead = reader.read(buf)) != -1) {
+ String readData = String.valueOf(buf, 0, numRead);
+ fileData.append(readData);
+ buf = new char[1024];
+ }
+ return fileData.toString();
+ } finally {
+ reader.close();
+ }
+ }
+
+ protected ExecutionContext context = new ExecutionContext();
+ protected boolean print = true;
+
+ public Parser() {
+ NamespaceRegistry registry = context.getNamespaceRegistry();
+ registry.register("ddl", "http://www.modeshape.org/ddl/1.0");
+ registry.register("postgres", "http://www.modeshape.org/ddl/postgres/1.0");
+ registry.register("oracle", "http://www.modeshape.org/ddl/oracle/1.0");
+ registry.register("mysql", "http://www.modeshape.org/ddl/mysql/1.0");
+ registry.register("derby", "http://www.modeshape.org/ddl/derby/1.0");
+ registry.register("sqlserver", "http://www.modeshape.org/ddl/sqlserver/1.0");
+ registry.register("sybase", "http://www.modeshape.org/ddl/sybase/1.0");
+ registry.register("db2", "http://www.modeshape.org/ddl/db2/1.0");
+ }
+
+ public Database parse( File file ) throws IOException {
+ // Read the file into a single string ...
+ String ddl = readFile(file);
+
+ // Create the object that will parse the file ...
+ DdlParsers parsers = new DdlParsers();
+ AstNode node = parsers.parse(ddl, file.getName());
+
+ // Now process the AST ...
+ System.out.println(node.getString(context));
+ return processStatements(node);
+ }
+
+ /**
+ * Process the top-level 'ddl:statements' node, which contains information about the parsed content.
+ *
+ * @param node the node; may not be null
+ * @return the database
+ */
+ protected Database processStatements( AstNode node ) {
+ assert node.getName().equals(StandardDdlLexicon.STATEMENTS_CONTAINER);
+
+ // Get the dialect that we've inferred ...
+ String dialectId = string(node.getProperty(StandardDdlLexicon.PARSER_ID).getFirstValue());
+
+ // Now process the children of the statements node ...
+ Database database = new Database(dialectId);
+ processChildrenOf(node, database);
+ return database;
+ }
+
+ protected void processChildrenOf( AstNode node,
+ NamedComponent parent ) {
+ for (AstNode child : node) {
+ process(child, parent);
+ }
+ }
+
+ protected void process( AstNode node,
+ NamedComponent parent ) {
+ Name mixin = name(node.getProperty(JcrLexicon.MIXIN_TYPES).getFirstValue());
+
+ // There are lots of different types of AST nodes, but we're only going to process a few ...
+
+ if (TYPE_CREATE_SCHEMA_STATEMENT.equals(mixin)) processCreateSchema(node, (SchemaContainer)parent);
+ else if (TYPE_DROP_SCHEMA_STATEMENT.equals(mixin)) processDropSchema(node, (SchemaContainer)parent);
+
+ else if (TYPE_CREATE_TABLE_STATEMENT.equals(mixin)) processCreateTable(node, (TableContainer)parent);
+ else if (TYPE_ALTER_TABLE_STATEMENT.equals(mixin)) processAlterTable(node, (TableContainer)parent);
+ else if (TYPE_DROP_TABLE_STATEMENT.equals(mixin)) processDropTable(node, (TableContainer)parent);
+
+ else if (TYPE_CREATE_VIEW_STATEMENT.equals(mixin)) processCreateView(node, (ViewContainer)parent);
+ else if (TYPE_DROP_VIEW_STATEMENT.equals(mixin)) processDropView(node, (ViewContainer)parent);
+
+ else if (TYPE_COLUMN_DEFINITION.equals(mixin)) processColumnDefinition(node, (ColumnContainer)parent);
+ else if (TYPE_ADD_COLUMN_DEFINITION.equals(mixin)) processColumnDefinition(node, (ColumnContainer)parent);
+ else if (TYPE_ALTER_COLUMN_DEFINITION.equals(mixin)) processColumnDefinition(node, (ColumnContainer)parent);
+ }
+
+ protected void processCreateSchema( AstNode node,
+ SchemaContainer parent ) {
+ String name = string(node.getName());
+ print("Create schema \"" + name + "\"");
+ Schema schema = parent.getSchema(name, true);
+ processChildrenOf(node, schema);
+ }
+
+ protected void processDropSchema( AstNode node,
+ SchemaContainer parent ) {
+ String name = string(node.getName());
+ print("Drop schema \"" + name + "\"");
+ parent.getSchemas().remove(name);
+ }
+
+ protected void processCreateTable( AstNode node,
+ TableContainer parent ) {
+ String name = string(node.getName());
+ print("Create table \"" + name + "\"");
+ Table table = parent.getTable(name, true);
+ processChildrenOf(node, table);
+ }
+
+ protected void processAlterTable( AstNode node,
+ TableContainer parent ) {
+ String name = string(node.getName());
+ print("Alter table \"" + name + "\"");
+ Table table = parent.getTable(name, true);
+ processChildrenOf(node, table);
+ }
+
+ protected void processDropTable( AstNode node,
+ TableContainer parent ) {
+ String name = string(node.getName());
+ print("Drop table \"" + name + "\"");
+ parent.getTables().remove(name);
+ }
+
+ protected void processCreateView( AstNode node,
+ ViewContainer parent ) {
+ String name = string(node.getName());
+ print("Create view \"" + name + "\"");
+ View view = parent.getView(name, true);
+
+ Property prop = node.getProperty(DDL_EXPRESSION);
+ if (prop != null) view.expression = string(prop.getFirstValue());
+
+ processChildrenOf(node, view);
+ }
+
+ protected void processDropView( AstNode node,
+ ViewContainer parent ) {
+ String name = string(node.getName());
+ print("Drop view \"" + name + "\"");
+ parent.getViews().remove(name);
+ }
+
+ protected void processColumnDefinition( AstNode node,
+ ColumnContainer parent ) {
+ String name = string(node.getName());
+ print("Column column \"" + name + "\"");
+ Column column = parent.getColumn(name, true);
+
+ Property prop = node.getProperty(DATATYPE_LENGTH);
+ if (prop != null) column.length = (int)number(prop.getFirstValue());
+
+ prop = node.getProperty(DATATYPE_NAME);
+ if (prop != null) column.datatypeName = string(prop.getFirstValue());
+
+ prop = node.getProperty(DATATYPE_PRECISION);
+ if (prop != null) column.precision = (int)number(prop.getFirstValue());
+
+ prop = node.getProperty(DATATYPE_SCALE);
+ if (prop != null) column.scale = (int)number(prop.getFirstValue());
+
+ prop = node.getProperty(DEFAULT_VALUE);
+ if (prop != null) column.defaultValue = string(prop.getFirstValue());
+ }
+
+ /**
+ * Convenience method to transform a property value into a string representation. Property values are often able to be
+ * tranformed into multiple types, so the ModeShape Graph API is designed so that you always convert the values into the
+ * desired type.
+ *
+ * @param value the property value; may be null
+ * @return the string representation of the value, or null if the value was null
+ */
+ protected String string( Object value ) {
+ return context.getValueFactories().getStringFactory().create(value);
+ }
+
+ protected Name name( Object value ) {
+ return context.getValueFactories().getNameFactory().create(value);
+ }
+
+ protected long number( Object value ) {
+ return context.getValueFactories().getLongFactory().create(value);
+ }
+
+ protected void print( String message ) {
+ if (print) System.out.println(message);
+ }
+
+ public static abstract class NamedComponent {
+ protected final String name;
+
+ protected NamedComponent( String name ) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ public static class Table extends NamedComponent implements ColumnContainer {
+ protected final Map<String, Column> columns = new LinkedHashMap<String, Column>();
+
+ public Table( String name ) {
+ super(name);
+ }
+
+ @Override
+ public Column getColumn( String name,
+ boolean createIfMissing ) {
+ Column column = columns.get(name);
+ if (column == null && createIfMissing) {
+ column = new Column(name);
+ columns.put(name, column);
+ }
+ return column;
+ }
+
+ @Override
+ public Map<String, Column> getColumns() {
+ return columns;
+ }
+ }
+
+ public static class View extends NamedComponent {
+ protected String expression;
+
+ public View( String name ) {
+ super(name);
+ }
+ }
+
+ public static class Column extends NamedComponent {
+ protected int length;
+ protected String datatypeName;
+ protected int precision;
+ protected int scale;
+ protected String defaultValue;
+
+ public Column( String name ) {
+ super(name);
+ }
+ }
+
+ public static interface SchemaContainer {
+ Schema getSchema( String name,
+ boolean createIfMissing );
+
+ Map<String, Schema> getSchemas();
+ }
+
+ public static interface TableContainer {
+ Table getTable( String name,
+ boolean createIfMissing );
+
+ Map<String, Table> getTables();
+ }
+
+ public static interface ViewContainer {
+ View getView( String name,
+ boolean createIfMissing );
+
+ Map<String, View> getViews();
+ }
+
+ public static interface ColumnContainer {
+ Column getColumn( String name,
+ boolean createIfMissing );
+
+ Map<String, Column> getColumns();
+ }
+
+ public static class Schema extends NamedComponent implements TableContainer, ViewContainer {
+ protected final Map<String, Table> tables = new LinkedHashMap<String, Table>();
+ protected final Map<String, View> views = new LinkedHashMap<String, View>();
+
+ public Schema( String name ) {
+ super(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.TableContainer#getTable(java.lang.String, boolean)
+ */
+ @Override
+ public Table getTable( String name,
+ boolean createIfMissing ) {
+ Table table = tables.get(name);
+ if (table == null && createIfMissing) {
+ table = new Table(name);
+ tables.put(name, table);
+ }
+ return table;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.TableContainer#getTables()
+ */
+ @Override
+ public Map<String, Table> getTables() {
+ return tables;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.ViewContainer#getView(java.lang.String, boolean)
+ */
+ @Override
+ public View getView( String name,
+ boolean createIfMissing ) {
+ View view = views.get(name);
+ if (view == null && createIfMissing) {
+ view = new View(name);
+ views.put(name, view);
+ }
+ return view;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.ViewContainer#getViews()
+ */
+ @Override
+ public Map<String, View> getViews() {
+ return views;
+ }
+ }
+
+ public static class Database extends NamedComponent implements TableContainer, ViewContainer, SchemaContainer {
+ protected final Map<String, Table> tables = new LinkedHashMap<String, Table>();
+ protected final Map<String, View> views = new LinkedHashMap<String, View>();
+ protected final Map<String, Schema> schemas = new LinkedHashMap<String, Schema>();
+
+ public Database( String name ) {
+ super(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.TableContainer#getTable(java.lang.String, boolean)
+ */
+ @Override
+ public Table getTable( String name,
+ boolean createIfMissing ) {
+ Table table = tables.get(name);
+ if (table == null && createIfMissing) {
+ table = new Table(name);
+ tables.put(name, table);
+ }
+ return table;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.TableContainer#getTables()
+ */
+ @Override
+ public Map<String, Table> getTables() {
+ return tables;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.ViewContainer#getView(java.lang.String, boolean)
+ */
+ @Override
+ public View getView( String name,
+ boolean createIfMissing ) {
+ View view = views.get(name);
+ if (view == null && createIfMissing) {
+ view = new View(name);
+ views.put(name, view);
+ }
+ return view;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.ViewContainer#getViews()
+ */
+ @Override
+ public Map<String, View> getViews() {
+ return views;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.SchemaContainer#getSchema(java.lang.String, boolean)
+ */
+ @Override
+ public Schema getSchema( String name,
+ boolean createIfMissing ) {
+ Schema schema = schemas.get(name);
+ if (schema == null && createIfMissing) {
+ schema = new Schema(name);
+ schemas.put(name, schema);
+ }
+ return schema;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.modeshape.example.ddl.Parser.SchemaContainer#getSchemas()
+ */
+ @Override
+ public Map<String, Schema> getSchemas() {
+ return schemas;
+ }
+ }
+
+}
View
62 modeshape-ddl-parser-example/src/main/resources/modeshape-config.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns:mode="http://www.modeshape.org/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0">
+ <!--
+ Define the JCR repositories
+ -->
+ <mode:repositories>
+ <!--
+ Define a JCR repository that accesses the 'Store' source
+ -->
+ <mode:repository jcr:name="My repository" mode:source="Store">
+ <mode:options jcr:primaryType="mode:options">
+ <mode:option jcr:name="systemSourceName" mode:value="system@Store"/>
+ <mode:option jcr:name="jaasLoginConfigName" mode:value="modeshape-jcr"/>
+ <!--
+ As a convenience, ModeShape defaults to granting guest users full access.
+ In a production system, you would want to limit this access by uncommenting one of the
+ options below:
+
+ for no access:
+ <mode:option jcr:name="anonymousUserRoles" mode:value="" />
+
+ for read-only acces:
+ <mode:option jcr:name="anonymousUserRoles" mode:value="readonly" />
+ -->
+ </mode:options>
+ </mode:repository>
+ </mode:repositories>
+ <!--
+ Define the sources for the content. These sources are directly accessible using the ModeShape-specific
+ Graph API.
+ -->
+ <mode:sources>
+ <mode:source jcr:name="Store" mode:classname="org.modeshape.graph.connector.inmemory.InMemoryRepositorySource" mode:retryLimit="3" mode:defaultWorkspaceName="default">
+ <predefinedWorkspaceNames>system</predefinedWorkspaceNames>
+ <predefinedWorkspaceNames>default</predefinedWorkspaceNames>
+ </mode:source>
+ </mode:sources>
+ <!--
+ Define the clustering configuration. This is an optional section; leave it out when
+ running in a non-clustered (single-process) mode.
+ -->
+ <!--mode:clustering clusterName="modeshape-cluster" configuration="jgroups-modeshape.xml"/-->
+
+ <!--
+ Define the sequencers. This is an optional section.
+ -->
+ <!--mode:sequencers>
+ <mode:sequencer jcr:name="Image Sequencer" mode:classname="org.modeshape.sequencer.image.ImageMetadataSequencer">
+ <mode:description>Image metadata sequencer</mode:description>
+ <mode:pathExpression>/foo/source =&gt; /foo/target</mode:pathExpression>
+ <mode:pathExpression>/bar/source =&gt; /bar/target</mode:pathExpression>
+ </mode:sequencer>
+ </mode:sequencers-->
+ <!--
+ Define how ModeShape will determine the MIME type of files. This is an optional section;
+ if you do not specify a MIME type detector, ModeShape will use a built-in one that is based
+ filename extensions for most commonly-used files.
+ -->
+ <!--mode:mimeTypeDetectors>
+ <mode:mimeTypeDetector jcr:name="Detector" mode:description="Standard extension-based MIME type detector"/>
+ </mode:mimeTypeDetectors-->
+</configuration>
View
90 modeshape-ddl-parser-example/src/test/java/org/modeshape/example/ddl/ParserTest.java
@@ -0,0 +1,90 @@
+/*
+ * ModeShape (http://www.modeshape.org)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * ModeShape 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 this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.modeshape.example.ddl;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.io.File;
+import java.util.Iterator;
+import org.junit.Before;
+import org.junit.Test;
+import org.modeshape.example.ddl.Parser.Column;
+import org.modeshape.example.ddl.Parser.Database;
+import org.modeshape.example.ddl.Parser.Schema;
+import org.modeshape.example.ddl.Parser.Table;
+import org.modeshape.example.ddl.Parser.View;
+
+/**
+ *
+ */
+public class ParserTest {
+
+ private Parser parser;
+ private Database database;
+
+ @Before
+ public void beforeEach() {
+ parser = new Parser();
+ }
+
+ @Test
+ public void shouldParseSql92CreateSchema() throws Exception {
+ database = parser.parse(testFile("create_schema.ddl"));
+ assertThat(database.getName(), is("POSTGRES"));
+ Schema schema = database.getSchema("hollywood", false);
+ assertThat(schema.getName(), is("hollywood"));
+ Table table = schema.getTable("films", false);
+ assertThat(table.getName(), is("films"));
+ Iterator<Column> columns = table.getColumns().values().iterator();
+ assertColumn(columns.next(), "title", "VARCHAR", null, 255, 0, 0);
+ assertColumn(columns.next(), "release", "DATE", null, 0, 0, 0);
+ assertColumn(columns.next(), "producerName", "VARCHAR", null, 255, 0, 0);
+ assertThat(columns.hasNext(), is(false));
+
+ View view = schema.getView("winners", false);
+ assertThat(view.getName(), is("winners"));
+ assertThat(view.expression, is("CREATE VIEW winners AS SELECT title, release FROM films WHERE producerName IS NOT NULL;"));
+ }
+
+ protected File testFile( String path ) {
+ return new File("src/test/resources/" + path);
+ }
+
+ protected Column assertColumn( Column actual,
+ String name,
+ String datatype,
+ String defaultValue,
+ int length,
+ int precision,
+ int scale ) {
+ assertThat(actual.getName(), is(name));
+ assertThat(actual.datatypeName, is(datatype));
+ assertThat(actual.defaultValue, is(defaultValue));
+ assertThat(actual.length, is(length));
+ assertThat(actual.precision, is(precision));
+ assertThat(actual.precision, is(scale));
+ return actual;
+ }
+
+}
View
74 modeshape-ddl-parser-example/src/test/resources/alter_table_statements.ddl
@@ -0,0 +1,74 @@
+-- ==================================================================
+-- ALTER TABLE Statement
+-- ==================================================================
+--<alter table statement> ::=
+-- ALTER TABLE <table name> <alter table action>
+--
+--<alter table action> ::=
+-- <add column definition>
+-- | <alter column definition>
+-- | <drop column definition>
+-- | <add table constraint definition>
+-- | <drop table constraint definition>
+--
+--<add column definition> ::=
+-- ADD [ COLUMN ] <column definition>
+--
+--<column definition> ::=
+-- <column name> { <data type> | <domain name> }
+-- [ <default clause> ]
+-- [ <column constraint definition>... ]
+-- [ <collate clause> ]
+
+ALTER TABLE table_name_1 ADD COLUMN column_name VARCHAR(25) NOT NULL;
+
+ALTER TABLE schema_2.table_name_2 ADD schema_2.table_name_2.column_name INTEGER NOT NULL DEFAULT (25);
+
+--<alter column definition> ::=
+-- ALTER [ COLUMN ] <column name> <alter column action>
+--
+--<alter column action> ::=
+-- <set column default clause>
+-- | <drop column default clause>
+--
+--<set column default clause> ::=
+-- SET <default clause>
+--
+--<drop column default clause> ::=
+-- DROP DEFAULT
+--
+
+ALTER TABLE table_name_3 ALTER column_name SET DEFAULT (0);
+
+ALTER TABLE table_name_4 ALTER COLUMN column_name SET DEFAULT (0);
+
+ALTER TABLE table_name_5 ALTER column_name DROP DEFAULT;
+
+--<drop column definition> ::=
+-- DROP [ COLUMN ] <column name> <drop behavior>
+--
+ALTER TABLE table_name_6 DROP COLUMN column_name CASCADE;
+
+ALTER TABLE table_name_7 DROP COLUMN column_name RESTRICT;
+
+ALTER TABLE table_name_8 DROP column_name CASCADE;
+
+ALTER TABLE table_name_9 DROP column_name RESTRICT;
+
+--<add table constraint definition> ::=
+-- ADD <table constraint definition>
+--
+
+ALTER TABLE table_name_10 ADD CONSTRAINT pk_name PRIMARY KEY (column_name);
+
+ALTER TABLE table_name_11 ADD CONSTRAINT pk_name PRIMARY KEY (column1_name, schema_name_11.table_name_11.column2_name);
+
+ALTER TABLE table_name_12 ADD CONSTRAINT fk_name FOREIGN KEY (ref_col_name) REFERENCES ref_table_name(ref_table_column_name);
+
+--<drop table constraint definition> ::=
+-- DROP CONSTRAINT <constraint name> <drop behavior>
+--
+
+ALTER TABLE table_name_13 DROP CONSTRAINT fk_name CASCADE;
+
+ALTER TABLE table_name_14 DROP CONSTRAINT fk_name RESTRICT;
View
3 modeshape-ddl-parser-example/src/test/resources/create_schema.ddl
@@ -0,0 +1,3 @@
+CREATE SCHEMA hollywood
+ CREATE TABLE films (title varchar(255), release date, producerName varchar(255))
+ CREATE VIEW winners AS SELECT title, release FROM films WHERE producerName IS NOT NULL;
View
218 modeshape-ddl-parser-example/src/test/resources/derby/derby_test_statements.ddl
@@ -0,0 +1,218 @@
+--
+-- SAMPLE DERBY STATEMENTS
+--
+
+-- Add a new column with a column-level constraint
+-- to an existing table
+-- An exception will be thrown if the table
+-- contains any rows
+-- since the newcol will be initialized to NULL
+-- in all existing rows in the table
+ALTER TABLE CITIES ADD COLUMN REGION VARCHAR(26)
+ CONSTRAINT NEW_CONSTRAINT CHECK (REGION IS NOT NULL);
+
+-- Add a new unique constraint to an existing table
+-- An exception will be thrown if duplicate keys are found
+ALTER TABLE SAMP.DEPARTMENT
+ ADD CONSTRAINT NEW_UNIQUE UNIQUE (DEPTNO);
+
+-- add a new foreign key constraint to the
+-- Cities table. Each row in Cities is checked
+-- to make sure it satisfied the constraints.
+-- if any rows don't satisfy the constraint, the
+-- constraint is not added
+ALTER TABLE CITIES ADD CONSTRAINT COUNTRY_FK
+ Foreign Key (COUNTRY) REFERENCES COUNTRIES (COUNTRY);
+
+-- Add a primary key constraint to a table
+-- First, create a new table
+CREATE TABLE ACTIVITIES (CITY_ID INT NOT NULL,
+ SEASON CHAR(2), ACTIVITY VARCHAR(32) NOT NULL);
+-- You will not be able to add this constraint if the
+-- columns you are including in the primary key have
+-- null data or duplicate values.
+ALTER TABLE Activities ADD PRIMARY KEY (city_id, activity);
+
+-- Drop the city_id column if there are no dependent objects:
+ALTER TABLE Cities DROP COLUMN city_id RESTRICT;
+-- Drop the city_id column, also dropping all dependent objects:
+ALTER TABLE Cities DROP COLUMN city_id CASCADE;
+
+-- Drop a primary key constraint from the CITIES table
+
+ALTER TABLE Cities DROP CONSTRAINT Cities_PK;
+-- Drop a foreign key constraint from the CITIES table
+ALTER TABLE Cities DROP CONSTRAINT COUNTRIES_FK;
+-- add a DEPTNO column with a default value of 1
+ALTER TABLE SAMP.EMP_ACT ADD COLUMN DEPTNO INT DEFAULT 1;
+-- increase the width of a VARCHAR column
+ALTER TABLE SAMP.EMP_PHOTO ALTER PHOTO_FORMAT SET DATA TYPE VARCHAR(30);
+-- change the lock granularity of a table
+ALTER TABLE SAMP.SALES LOCKSIZE TABLE;
+
+-- Remove the NOT NULL constraint from the MANAGER column
+ALTER TABLE Employees ALTER COLUMN Manager NULL;
+-- Add the NOT NULL constraint to the SSN column
+ALTER TABLE Employees ALTER COLUMN ssn NOT NULL;
+
+-- Change the default value for the SALARY column
+ALTER TABLE Employees ALTER COLUMN Salary DEFAULT 1000.0;
+ALTER TABLE Employees ALTER COLUMN Salary DROP DEFAULT;
+
+
+CREATE FUNCTION TO_DEGREES
+ ( RADIANS DOUBLE )
+ RETURNS DOUBLE
+ PARAMETER STYLE JAVA
+ NO SQL LANGUAGE JAVA
+ EXTERNAL NAME 'java.lang.Math.toDegrees';
+
+
+CREATE FUNCTION PROPERTY_FILE_READER
+ ( FILENAME VARCHAR( 32672 ) )
+ RETURNS TABLE
+ (
+ KEY_COL VARCHAR( 10 ),
+ VALUE_COL VARCHAR( 1000 )
+ )
+ LANGUAGE JAVA
+ PARAMETER STYLE DERBY_JDBC_RESULT_SET
+ NO SQL
+ EXTERNAL NAME 'vtis.example.PropertyFileVTI.propertyFileVTI';
+
+CREATE INDEX OrigIndex ON Flights(orig_airport);
+
+CREATE INDEX PAY_DESC ON SAMP.EMPLOYEE (SALARY);
+
+CREATE INDEX IXSALE ON SAMP.SALES (SALES);
+
+CREATE PROCEDURE SALES.TOTAL_REVENUE(IN S_MONTH INTEGER,
+ IN S_YEAR INTEGER, OUT TOTAL DECIMAL(10,2))
+ PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME
+ 'com.acme.sales.calculateRevenueByMonth';
+
+CREATE ROLE purchases_reader;
+
+CREATE ROLE purchases_reader_role;
+
+CREATE SCHEMA FLIGHTS AUTHORIZATION anita;
+
+CREATE SCHEMA EMP;
+
+CREATE SCHEMA AUTHORIZATION takumi;
+
+CREATE SYNONYM SAMP.T1 FOR SAMP.TABLEWITHLONGNAME;
+
+CREATE TABLE HOTELAVAILABILITY
+ (HOTEL_ID INT NOT NULL, BOOKING_DATE DATE NOT NULL,
+ ROOMS_TAKEN INT DEFAULT 0, PRIMARY KEY (HOTEL_ID, BOOKING_DATE));
+
+CREATE TABLE PEOPLE
+ (PERSON_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY
+ CONSTRAINT PEOPLE_PK PRIMARY KEY, PERSON VARCHAR(26));
+
+CREATE TABLE greetings
+ (i int generated by default as identity (START WITH 2, INCREMENT BY 1), ch char(50));
+
+CREATE TABLE GROUPS
+ (GROUP_ID SMALLINT NOT NULL GENERATED ALWAYS AS IDENTITY
+ (START WITH 5, INCREMENT BY 5), ADDRESS VARCHAR(100), PHONE VARCHAR(15));
+
+CREATE TRIGGER t1 NO CASCADE BEFORE UPDATE ON x
+ FOR EACH ROW MODE DB2SQL
+ values app.notifyEmail('Jerry', 'Table x is about to be updated');
+
+
+CREATE TRIGGER FLIGHTSDELETE
+ AFTER DELETE ON FLIGHTS
+ REFERENCING OLD_TABLE AS DELETEDFLIGHTS
+ FOR EACH STATEMENT
+ DELETE FROM FLIGHTAVAILABILITY WHERE FLIGHT_ID IN
+ (SELECT FLIGHT_ID FROM DELETEDFLIGHTS);
+
+CREATE TRIGGER FLIGHTSDELETE3
+ AFTER DELETE ON FLIGHTS
+ REFERENCING OLD AS OLD
+ FOR EACH ROW
+ DELETE FROM FLIGHTAVAILABILITY WHERE FLIGHT_ID = OLD.FLIGHT_ID;
+
+
+
+CREATE VIEW SAMP.V1 (COL_SUM, COL_DIFF)
+ AS SELECT COMM + BONUS, COMM - BONUS
+ FROM SAMP.EMPLOYEE;
+
+CREATE VIEW SAMP.VEMP_RES (RESUME)
+ AS VALUES 'Delores M. Quintana', 'Heather A. Nicholls', 'Bruce Adamson';
+
+CREATE VIEW SAMP.PROJ_COMBO
+ (PROJNO, PRENDATE, PRSTAFF, MAJPROJ)
+ AS SELECT PROJNO, PRENDATE, PRSTAFF, MAJPROJ
+ FROM SAMP.PROJECT UNION ALL
+ SELECT PROJNO, EMSTDATE, EMPTIME, EMPNO
+ FROM SAMP.EMP_ACT
+ WHERE EMPNO IS NOT NULL;
+
+CREATE VIEW V1 (C1) AS SELECT SIN(C1) FROM T1;
+
+declare global temporary table SESSION.t1(c11 int) not logged;
+-- The SESSION qualification is redundant here because temporary
+-- tables can only exist in the SESSION schema.
+
+declare global temporary table t2(c21 int) not logged;
+-- The temporary table is not qualified here with SESSION because temporary
+-- tables can only exist in the SESSION schema.
+
+DROP FUNCTION some_function_name;
+
+DROP INDEX OrigIndex;
+
+DROP INDEX DestIndex;
+
+DROP PROCEDURE some_procedure_name;
+
+DROP ROLE reader;
+
+-- The RESTRICT keyword is required
+DROP SCHEMA SAMP RESTRICT;
+
+DROP SYNONYM some_synonym_name;
+
+DROP TABLE some_table_name;
+
+DROP TRIGGER TRIG1;
+
+DROP VIEW AnIdentifier;
+
+GRANT SELECT ON TABLE t TO maria,harry;
+
+GRANT UPDATE, TRIGGER ON TABLE t TO anita,zhi;
+
+GRANT SELECT ON TABLE s.v to PUBLIC;
+
+GRANT EXECUTE ON PROCEDURE p TO george;
+
+GRANT purchases_reader_role TO george,maria;
+
+GRANT SELECT ON TABLE t TO purchases_reader_role;
+
+INSERT INTO COUNTRIES
+ VALUES ('Taiwan', 'TW', 'Asia');
+
+INSERT INTO MA_EMP_ACT
+ SELECT * FROM EMP_ACT
+ WHERE SUBSTR(PROJNO, 1, 2) = 'MA';
+
+-- Insert the DEFAULT value for the LOCATION column
+INSERT INTO DEPARTMENT
+ VALUES ('E31', 'ARCHITECTURE', '00390', 'E01', DEFAULT);
+
+LOCK TABLE FlightAvailability IN EXCLUSIVE MODE;
+
+LOCK TABLE Maps IN EXCLUSIVE MODE;
+
+RENAME INDEX DESTINDEX TO ARRIVALINDEX;
+
+RENAME TABLE SAMP.EMP_ACT TO EMPLOYEE_ACT;
+
+
View
7 modeshape-ddl-parser-example/src/test/resources/grant_test_statements.ddl
@@ -0,0 +1,7 @@
+GRANT SELECT ON TABLE purchaseOrders TO maria,harry;
+
+GRANT UPDATE, USAGE ON TABLE billedOrders TO anita,zhi;
+
+GRANT SELECT ON TABLE orders.bills to PUBLIC;
+
+GRANT INSERT(a, b, c) ON TABLE purchaseOrders TO purchases_reader_role;
View
11 modeshape-ddl-parser-example/src/test/resources/log4j.properties
@@ -0,0 +1,11 @@
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Set up the default logging to be INFO level, then override specific units
+log4j.logger.org.modeshape=INFO
View
24 modeshape-ddl-parser-example/src/test/resources/oracle/create_procedure_statements.ddl
@@ -0,0 +1,24 @@
+CREATE PROCEDURE remove_emp (employee_id NUMBER) AS tot_emps NUMBER;
+ BEGIN
+ DELETE FROM employees
+ WHERE employees.employee_id = remove_emp.employee_id;
+ tot_emps := tot_emps - 1;
+ END;
+/
+
+CREATE PROCEDURE find_root
+ ( x IN REAL )
+ IS LANGUAGE C
+ NAME c_find_root
+ LIBRARY c_utils
+ PARAMETERS ( x BY REFERENCE );
+
+CREATE FUNCTION SecondMax (input NUMBER) RETURN NUMBER
+ PARALLEL_ENABLE AGGREGATE USING SecondMaxImpl;
+
+CREATE OR REPLACE FUNCTION text_length(a CLOB)
+ RETURN NUMBER DETERMINISTIC IS
+ BEGIN
+ RETURN DBMS_LOB.GETLENGTH(a);
+ END;
+/
View
234 modeshape-ddl-parser-example/src/test/resources/oracle/oracle_test_statements.ddl
@@ -0,0 +1,234 @@
+--
+-- SAMPLE ORACLE STATEMENTS
+--
+
+ALTER TABLE employees
+ PCTFREE 30
+ PCTUSED 60;
+
+ALTER TABLE countries
+ ADD (duty_pct NUMBER(2,2) CHECK (duty_pct < 10.5),
+ visa_needed VARCHAR2(3));
+
+ALTER TABLESPACE tbs_01
+ BEGIN BACKUP;
+
+ALTER TABLESPACE omf_ts1 ADD DATAFILE;
+
+ALTER TABLESPACE undots1
+ RETENTION NOGUARANTEE;
+
+ALTER TRIGGER update_job_history DISABLE;
+
+ALTER TYPE data_typ
+ ADD MEMBER FUNCTION qtr(der_qtr DATE)
+ RETURN CHAR CASCADE;
+
+ALTER TYPE cust_address_typ
+ ADD ATTRIBUTE (phone phone_list_typ) CASCADE;
+
+ALTER TYPE phone_list_typ
+ MODIFY ELEMENT TYPE VARCHAR(64) CASCADE;
+
+ALTER USER app_user1
+ GRANT CONNECT THROUGH sh
+ WITH ROLE warehouse_user;
+
+-- 10 Statements
+
+ALTER USER app_user1 IDENTIFIED GLOBALLY AS 'CN=tom,O=oracle,C=US';
+
+ALTER USER sidney
+ IDENTIFIED BY second_2nd_pwd
+ DEFAULT TABLESPACE example;
+
+ALTER VIEW customer_ro
+ COMPILE;
+
+ANALYZE TABLE customers VALIDATE STRUCTURE ONLINE;
+
+ANALYZE TABLE employees VALIDATE STRUCTURE CASCADE;
+
+ANALYZE TABLE orders DELETE STATISTICS;
+
+ASSOCIATE STATISTICS WITH PACKAGES emp_mgmt DEFAULT SELECTIVITY 10;
+
+AUDIT SELECT
+ ON hr.employees
+ WHENEVER SUCCESSFUL;
+
+AUDIT INSERT, UPDATE
+ ON oe.customers;
+
+AUDIT DELETE ANY TABLE;
+
+-- 20 Statements
+
+AUDIT ROLE
+ WHENEVER SUCCESSFUL;
+
+COMMENT ON COLUMN employees.job_id
+ IS 'abbreviated job title';
+
+COMMIT WORK;
+
+COMMIT COMMENT 'In-doubt transaction Code 36, Call (415) 555-2637';
+
+CREATE CLUSTER personnel
+ (department NUMBER(4))
+SIZE 512
+STORAGE (initial 100K next 50K);
+
+CREATE CLUSTER address
+ (postal_code NUMBER, country_id CHAR(2))
+ HASHKEYS 20
+ HASH IS MOD(postal_code + country_id, 101);
+
+CREATE CLUSTER cust_orders (customer_id NUMBER(6))
+ SIZE 512 SINGLE TABLE HASHKEYS 100;
+
+CREATE CONTEXT hr_context USING emp_mgmt;
+
+CREATE CONTROLFILE REUSE DATABASE "demo" NORESETLOGS NOARCHIVELOG
+ MAXLOGFILES 32
+ MAXLOGMEMBERS 2
+ MAXDATAFILES 32
+ MAXINSTANCES 1
+ MAXLOGHISTORY 449
+ LOGFILE
+ GROUP 1 '/path/oracle/dbs/t_log1.f' SIZE 500K,
+ GROUP 2 '/path/oracle/dbs/t_log2.f' SIZE 500K
+ # STANDBY LOGFILE
+ DATAFILE
+ '/path/oracle/dbs/t_db1.f',
+ '/path/oracle/dbs/dbu19i.dbf',
+ '/path/oracle/dbs/tbs_11.f',
+ '/path/oracle/dbs/smundo.dbf',
+ '/path/oracle/dbs/demo.dbf'
+ CHARACTER SET WE8DEC
+ ;
+
+CREATE DATABASE sample
+ CONTROLFILE REUSE
+ LOGFILE
+ GROUP 1 ('diskx:log1.log', 'disky:log1.log') SIZE 50K,
+ GROUP 2 ('diskx:log2.log', 'disky:log2.log') SIZE 50K
+ MAXLOGFILES 5
+ MAXLOGHISTORY 100
+ MAXDATAFILES 10
+ MAXINSTANCES 2
+ ARCHIVELOG
+ CHARACTER SET AL32UTF8
+ NATIONAL CHARACTER SET AL16UTF16
+ DATAFILE
+ 'disk1:df1.dbf' AUTOEXTEND ON,
+ 'disk2:df2.dbf' AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED
+ DEFAULT TEMPORARY TABLESPACE temp_ts
+ UNDO TABLESPACE undo_ts
+ SET TIME_ZONE = '+02:00';
+
+-- 30 Statements
+
+CREATE PUBLIC DATABASE LINK remote
+ USING 'remote';
+
+CREATE DATABASE LINK local
+ CONNECT TO hr IDENTIFIED BY hr
+ USING 'local';
+
+CREATE DIMENSION customers_dim
+ LEVEL customer IS (customers.cust_id)
+ LEVEL city IS (customers.cust_city)
+ LEVEL state IS (customers.cust_state_province)
+ LEVEL country IS (countries.country_id)
+ LEVEL subregion IS (countries.country_subregion)
+ LEVEL region IS (countries.country_region)
+ HIERARCHY geog_rollup (
+ customer CHILD OF
+ city CHILD OF
+ state CHILD OF
+ country CHILD OF
+ subregion CHILD OF
+ region
+ JOIN KEY (customers.country_id) REFERENCES country
+ )
+ ATTRIBUTE customer DETERMINES
+ (cust_first_name, cust_last_name, cust_gender,
+ cust_marital_status, cust_year_of_birth,
+ cust_income_level, cust_credit_limit)
+ ATTRIBUTE country DETERMINES (countries.country_name)
+;
+
+CREATE DIRECTORY admin AS 'oracle/admin';
+
+CREATE OR REPLACE DIRECTORY bfile_dir AS '/private1/LOB/files';
+
+CREATE DISKGROUP dgroup_01
+ EXTERNAL REDUNDANCY
+ DISK '$ORACLE_HOME/disks/c*';
+
+CREATE FUNCTION SecondMax (input NUMBER) RETURN NUMBER
+ PARALLEL_ENABLE AGGREGATE USING SecondMaxImpl;
+
+CREATE OR REPLACE FUNCTION text_length(a CLOB)
+ RETURN NUMBER DETERMINISTIC IS
+ BEGIN
+ RETURN DBMS_LOB.GETLENGTH(a);
+ END;
+/
+
+CREATE INDEXTYPE position_indextype
+ FOR position_between(NUMBER, NUMBER, NUMBER)
+ USING position_im;
+
+CREATE JAVA SOURCE NAMED "Hello" AS
+ public class Hello {
+ public static String hello() {
+ return \"Hello World\"; } };
+
+-- 40 Statements
+
+CREATE JAVA RESOURCE NAMED "appText"
+ USING BFILE (bfile_dir, 'textBundle.dat');
+
+CREATE LIBRARY ext_lib AS '/OR/lib/ext_lib.so';
+/
+
+CREATE OR REPLACE LIBRARY ext_lib IS '/OR/newlib/ext_lib.so';
+/
+
+CREATE LIBRARY app_lib as '${ORACLE_HOME}/lib/app_lib.so'
+ AGENT 'sales.hq.acme.com';
+/
+
+CREATE MATERIALIZED VIEW LOG ON employees
+ WITH PRIMARY KEY
+ INCLUDING NEW VALUES;
+
+CREATE MATERIALIZED VIEW all_customers
+ PCTFREE 5 PCTUSED 60
+ TABLESPACE example
+ STORAGE (INITIAL 50K NEXT 50K)
+ USING INDEX STORAGE (INITIAL 25K NEXT 25K)
+ REFRESH START WITH ROUND(SYSDATE + 1) + 11/24
+ NEXT NEXT_DAY(TRUNC(SYSDATE), 'MONDAY') + 15/24
+ AS SELECT * FROM sh.customers@remote
+ UNION
+ SELECT * FROM sh.customers@local;
+
+CREATE MATERIALIZED VIEW LOG ON product_information
+ WITH ROWID, SEQUENCE (list_price, min_price, category_id)
+ INCLUDING NEW VALUES;
+
+CREATE OPERATOR eq_op
+ BINDING (VARCHAR2, VARCHAR2)
+ RETURN NUMBER
+ USING eq_f;
+
+CREATE OUTLINE salaries FOR CATEGORY special
+ ON SELECT last_name, salary FROM employees;
+
+CREATE OR REPLACE OUTLINE public_salaries
+ FROM PRIVATE my_salaries;
+
+-- 50 Statements so far
View
609 modeshape-ddl-parser-example/src/test/resources/postgres/postgres_test_statements.ddl
@@ -0,0 +1,609 @@
+-- Postgres SQL Statements from postgressql-8.4.1-US.pdf
+--
+-- Extracted 10/5/2009
+
+--COMMENT ON
+--{
+-- TABLE object_name |
+-- COLUMN table_name.column_name |
+-- AGGREGATE agg_name (agg_type [, ...] ) |
+-- CAST (sourcetype AS targettype) |
+-- CONSTRAINT constraint_name ON table_name |
+-- CONVERSION object_name |
+-- DATABASE object_name |
+-- DOMAIN object_name |
+-- FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) |
+-- INDEX object_name |
+-- LARGE OBJECT large_object_oid |
+-- OPERATOR op (leftoperand_type, rightoperand_type) |
+-- OPERATOR CLASS object_name USING index_method |
+-- OPERATOR FAMILY object_name USING index_method |
+-- [ PROCEDURAL ] LANGUAGE object_name |
+-- ROLE object_name |
+-- RULE rule_name ON table_name |
+-- SCHEMA object_name |
+-- SEQUENCE object_name |
+-- TABLESPACE object_name |
+-- TEXT SEARCH CONFIGURATION object_name |
+-- TEXT SEARCH DICTIONARY object_name |
+-- TEXT SEARCH PARSER object_name |
+-- TEXT SEARCH TEMPLATE object_name |
+-- TRIGGER trigger_name ON table_name |
+-- TYPE object_name |
+-- VIEW object_name
+--} IS 'text'
+
+COMMENT ON TABLE mytable IS 'This is my table.';
+COMMENT ON TABLE mytable IS NULL;
+COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
+COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4';
+COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
+COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8';
+COMMENT ON DATABASE my_database IS 'Development Database';
+COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
+COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
+COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee ID';
+-- 10 STATEMENTS *******************************************************
+COMMENT ON LANGUAGE plpython IS 'Python support for stored procedures';
+COMMENT ON LARGE OBJECT 346344 IS 'Planning document';
+COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
+COMMENT ON OPERATOR - (NONE, text) IS 'This is a prefix operator on text';
+COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees';
+COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees';
+COMMENT ON ROLE my_role IS 'Administration group for finance tables';
+COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records';
+COMMENT ON SCHEMA my_schema IS 'Departmental data';
+COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
+-- 20 STATEMENTS *******************************************************
+COMMENT ON TABLE my_schema.my_table IS 'Employee Information';
+COMMENT ON TABLESPACE my_tablespace IS 'Tablespace for indexes';
+COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Special word filtering';
+COMMENT ON TEXT SEARCH DICTIONARY swedish IS 'Snowball stemmer for swedish language';
+COMMENT ON TEXT SEARCH PARSER my_parser IS 'Splits text into words';
+COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Snowball stemmer';
+COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI';
+COMMENT ON TYPE complex IS 'Complex number data type';
+COMMENT ON VIEW my_view IS 'View of departmental costs';
+--COMMIT [ WORK | TRANSACTION ]
+
+COMMIT WORK;
+-- 30 STATEMENTS *******************************************************
+COMMIT TRANSACTION;
+
+COMMIT;
+
+--COMMIT PREPARED transaction_id;
+
+COMMIT PREPARED 'foobar';
+
+--COPY tablename [ ( column [, ...] ) ]
+-- FROM { 'filename' | STDIN }
+-- [ [ WITH ]
+-- [ BINARY ]
+-- [ OIDS ]
+-- [ DELIMITER [ AS ] 'delimiter ' ]
+-- [ NULL [ AS ] 'null string ' ]
+-- [ CSV [ HEADER ]
+-- [ QUOTE [ AS ] 'quote' ]
+-- [ ESCAPE [ AS ] 'escape' ]
+-- [ FORCE NOT NULL column [, ...] ]
+--COPY { tablename [ ( column [, ...] ) ] | ( query ) }
+-- TO { 'filename' | STDOUT }
+-- [ [ WITH ]
+-- [ BINARY ]
+-- [ OIDS ]
+-- [ DELIMITER [ AS ] 'delimiter ' ]
+-- [ NULL [ AS ] 'null string ' ]
+-- [ CSV [ HEADER ]
+-- [ QUOTE [ AS ] 'quote' ]
+-- [ ESCAPE [ AS ] 'escape' ]
+-- [ FORCE QUOTE column [, ...] ]
+
+COPY country TO STDOUT WITH DELIMITER '|';
+
+COPY country FROM '/usr1/proj/bray/sql/country_data';
+
+COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_co';
+
+--CREATE AGGREGATE name ( input_data_type [ , ... ] ) (
+-- SFUNC = sfunc,
+-- STYPE = state_data_type
+-- [ , FINALFUNC = ffunc ]
+-- [ , INITCOND = initial_condition ]
+-- [ , SORTOP = sort_operator ]
+--)
+--or the old syntax
+--CREATE AGGREGATE name (
+-- BASETYPE = base_type,
+-- SFUNC = sfunc,
+-- STYPE = state_data_type
+-- [ , FINALFUNC = ffunc ]
+-- [ , INITCOND = initial_condition ]
+-- [ , SORTOP = sort_operator ]
+--)
+
+
+--CREATE CAST (sourcetype AS targettype)
+-- WITH FUNCTION funcname (argtypes)
+-- [ AS ASSIGNMENT | AS IMPLICIT ]
+--CREATE CAST (sourcetype AS targettype)
+-- WITHOUT FUNCTION
+-- [ AS ASSIGNMENT | AS IMPLICIT ]
+--CREATE CAST (sourcetype AS targettype)
+-- WITH INOUT
+-- [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
+
+--CREATE CONSTRAINT TRIGGER name
+-- AFTER event [ OR ... ]
+-- ON table_name
+-- [ FROM referenced_table_name ]
+-- { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }
+-- FOR EACH ROW
+-- EXECUTE PROCEDURE funcname ( arguments )
+
+--CREATE [ DEFAULT ] CONVERSION name
+-- FOR source_encoding TO dest_encoding FROM funcname
+
+CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;
+
+--CREATE DATABASE name
+-- [ [ WITH ] [ OWNER [=] dbowner ]
+-- [ TEMPLATE [=] template ]
+-- [ ENCODING [=] encoding ]
+-- [ LC_COLLATE [=] lc_collate ]
+-- [ LC_CTYPE [=] lc_ctype ]
+-- [ TABLESPACE [=] tablespace ]
+-- [ CONNECTION LIMIT [=] connlimit ] ]
+
+CREATE DATABASE lusiadas;
+
+CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;
+-- 40 STATEMENTS *******************************************************
+CREATE DATABASE music ENCODING 'LATIN1' TEMPLATE template0;
+
+
+--CREATE DOMAIN name [ AS ] data_type
+-- [ DEFAULT expression ]
+-- [ constraint [ ... ] ]
+--where constraint is:
+--[ CONSTRAINT constraint_name ]
+--{ NOT NULL | NULL | CHECK (expression) }
+
+CREATE DOMAIN us_postal_code AS TEXT
+ CHECK(
+ VALUE ~ '^\\d{5}$'
+ OR VALUE ~ '^\\d{5}-\\d{4}$'
+ );
+
+--CREATE FOREIGN DATA WRAPPER name
+-- [ VALIDATOR valfunction | NO VALIDATOR ]
+-- [ OPTIONS ( option 'value' [, ... ] ) ]
+
+CREATE FOREIGN DATA WRAPPER dummy;
+
+CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
+
+CREATE FOREIGN DATA WRAPPER mywrapper
+ OPTIONS (debug 'true');
+
+--CREATE [ OR REPLACE ] FUNCTION
+-- name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } defexpr ] [, ...] ] )
+-- [ RETURNS rettype
+-- | RETURNS TABLE ( colname coltype [, ...] ) ]
+-- { LANGUAGE langname
+-- | WINDOW
+-- | IMMUTABLE | STABLE | VOLATILE
+-- | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
+-- | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+-- | COST execution_cost
+-- | ROWS result_rows
+-- | SET configuration_parameter { TO value | = value | FROM CURRENT }
+-- | AS 'definition'
+-- | AS 'obj_file', 'link_symbol'
+-- } ...
+-- [ WITH ( attribute [, ...] ) ]
+
+CREATE FUNCTION add(integer, integer) RETURNS integer
+ AS 'select $1 + $2;'
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT;
+
+CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
+ BEGIN
+ RETURN i + 1;
+ END;
+
+CREATE FUNCTION dup(in int, out f1 int, out f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+CREATE FUNCTION dup(int) RETURNS dup_result
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+-- 50 STATEMENTS *******************************************************
+--CREATE GROUP name [ [ WITH ] option [ ... ] ]
+--where option can be:
+-- SUPERUSER | NOSUPERUSER
+-- | CREATEDB | NOCREATEDB
+-- | CREATEROLE | NOCREATEROLE
+-- | CREATEUSER | NOCREATEUSER
+-- | INHERIT | NOINHERIT
+-- | LOGIN | NOLOGIN
+-- | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password '
+-- | VALID UNTIL 'timestamp'
+-- | IN ROLE rolename [, ...]
+-- | IN GROUP rolename [, ...]
+-- | ROLE rolename [, ...]
+-- | ADMIN rolename [, ...]
+-- | USER rolename [, ...]
+-- | SYSID uid
+
+--CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]
+-- ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ..
+-- [ WITH ( storage_parameter = value [, ... ] ) ]
+-- [ TABLESPACE tablespace ]
+-- [ WHERE predicate ]
+
+CREATE UNIQUE INDEX title_idx ON films (title);
+
+CREATE INDEX lower_title_idx ON films ((lower(title)));
+
+CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
+
+CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);
+
+CREATE INDEX gin_idx ON documents_table (locations) WITH (fastupdate = off);
+
+CREATE INDEX code_idx ON films(code) TABLESPACE indexspace;
+
+CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
+
+--CREATE [ PROCEDURAL ] LANGUAGE name
+--CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name
+-- HANDLER call_handler [ VALIDATOR valfunction ]
+
+CREATE LANGUAGE plpgsql;
+
+CREATE PROCEDURAL LANGUAGE plpgsql;
+
+CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql;
+-- 60 STATEMENTS *******************************************************
+CREATE LANGUAGE plsample
+ HANDLER plsample_call_handler;
+
+--CREATE OPERATOR name (
+-- PROCEDURE = funcname
+-- [, LEFTARG = lefttype ] [, RIGHTARG = righttype ]
+-- [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
+-- [, RESTRICT = res_proc ] [, JOIN = join_proc ]
+-- [, HASHES ] [, MERGES ]
+--)
+
+CREATE OPERATOR === (
+ LEFTARG = box,
+ RIGHTARG = box,
+ PROCEDURE = area_equal_procedure,
+ COMMUTATOR = ===,
+ NEGATOR = !==,
+ RESTRICT = area_restriction_procedure,
+ JOIN = area_join_procedure,
+ HASHES, MERGES
+);
+
+--CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type
+-- USING index_method [ FAMILY family_name ] AS
+-- { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ]
+-- | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )
+-- | STORAGE storage_type
+-- } [, ... ]
+
+CREATE OPERATOR CLASS gist__int_ops
+ DEFAULT FOR TYPE _int4 USING gist AS
+ OPERATOR 3 &&,
+ OPERATOR 6 = (anyarray, anyarray),
+ OPERATOR 7 @>,
+ <@,
+ OPERATOR 8
+ OPERATOR 20 @@ (_int4, query_int),
+ FUNCTION 1 g_int_consistent (internal, _int4, int, oid, internal),
+ FUNCTION 2 g_int_union (internal, internal),
+ FUNCTION 3 g_int_compress (internal),
+ FUNCTION 4 g_int_decompress (internal),
+ FUNCTION 5 g_int_penalty (internal, internal, internal),
+ FUNCTION 6 g_int_picksplit (internal, internal),
+ FUNCTION 7 g_int_same (_int4, _int4, internal);
+
+--CREATE OPERATOR FAMILY name USING index_method
+
+CREATE OPERATOR FAMILY name USING index_method;
+
+--CREATE ROLE name [ [ WITH ] option [ ... ] ]
+--where option can be:
+-- SUPERUSER | NOSUPERUSER
+-- | CREATEDB | NOCREATEDB
+-- | CREATEROLE | NOCREATEROLE
+-- | CREATEUSER | NOCREATEUSER
+-- | INHERIT | NOINHERIT
+-- | LOGIN | NOLOGIN
+-- | CONNECTION LIMIT connlimit
+-- | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password '
+-- | VALID UNTIL 'timestamp'
+-- | IN ROLE rolename [, ...]
+-- | IN GROUP rolename [, ...]
+-- | ROLE rolename [, ...]
+-- | ADMIN rolename [, ...]
+-- | USER rolename [, ...]
+-- | SYSID uid
+
+CREATE ROLE jonathan LOGIN;
+
+CREATE USER davide WITH PASSWORD 'jw8s0F4';
+
+CREATE ROLE miriam WITH LOGIN PASSWORD 'jw8s0F4' VALID UNTIL '2005-01-01';
+
+CREATE ROLE admin WITH CREATEDB CREATEROLE;
+
+--CREATE [ OR REPLACE ] RULE name AS ON event
+-- TO table [ WHERE condition ]
+-- DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }
+
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t1
+ DO INSTEAD
+ SELECT * FROM t2;
+
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t2
+ DO INSTEAD
+ SELECT * FROM t1;
+-- 70 STATEMENTS *******************************************************
+CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
+
+--CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]
+--CREATE SCHEMA AUTHORIZATION username [ schema_element [ ... ] ]
+
+CREATE SCHEMA myschema;
+
+CREATE SCHEMA AUTHORIZATION joe;
+
+CREATE SCHEMA hollywood
+ CREATE TABLE films (title text, release date, awards text[])
+ CREATE VIEW winners AS
+ SELECT title, release FROM films WHERE awards IS NOT NULL;
+
+--CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
+-- [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
+-- [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
+-- [ OWNED BY { table.column | NONE } ]
+
+CREATE SEQUENCE serial START 101;
+
+--CREATE SERVER servername [ TYPE 'servertype' ] [ VERSION 'serverversion' ]
+-- FOREIGN DATA WRAPPER fdwname
+-- [ OPTIONS ( option 'value' [, ... ] ) ]
+
+CREATE SERVER foo FOREIGN DATA WRAPPER "default";
+
+CREATE SERVER myserver FOREIGN DATA WRAPPER pgsql OPTIONS (host 'foo', dbname 'foodb', port);
+
+--CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name
+-- ( [
+-- { column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]
+-- | table_constraint
+-- | LIKE parent_table [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] .
+-- [, ... ]
+-- ] )
+--[ INHERITS ( parent_table [, ... ] ) ]
+--[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+--[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+--[ TABLESPACE tablespace ]
+--where column_constraint is:
+--[ CONSTRAINT constraint_name ]
+--{ NOT NULL |
+-- NULL |
+-- UNIQUE index_parameters |
+-- PRIMARY KEY index_parameters |
+-- CHECK ( expression ) |
+-- REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+-- [ ON DELETE action ] [ ON UPDATE action ] }
+--[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+--and table_constraint is:
+--[ CONSTRAINT constraint_name ]
+--{ UNIQUE ( column_name [, ... ] ) index_parameters |
+-- PRIMARY KEY ( column_name [, ... ] ) index_parameters |
+-- CHECK ( expression ) |
+-- FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
+-- [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ]
+--[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+--index_parameters in UNIQUE and PRIMARY KEY constraints are:
+--[ WITH ( storage_parameter [= value] [, ... ] ) ]
+--[ USING INDEX TABLESPACE tablespace ]
+
+CREATE TABLE films (
+ code char(5) CONSTRAINT firstkey PRIMARY KEY,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY DEFAULT nextval('serial'),
+ name varchar(40) NOT NULL CHECK (name <> ”)
+
+);
+
+CREATE TABLE array_int (
+ vector int[][]
+);
+-- 80 STATEMENTS *******************************************************
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT production UNIQUE(date_prod)
+);
+
+CREATE TABLE distributors (
+ did integer CHECK (did > 100),
+ name varchar(40)
+);
+
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40)
+ CONSTRAINT con1 CHECK (did > 100 AND name <> ”)
+);
+
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT code_title PRIMARY KEY(code,title)
+);
+
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT code_title PRIMARY KEY(code,title)
+);
+
+CREATE TABLE distributors (
+ name varchar(40) DEFAULT 'Luso Films',
+ did integer DEFAULT nextval('distributors_serial'),
+ modtime timestamp DEFAULT current_timestamp
+);
+
+CREATE TABLE distributors (
+ did integer CONSTRAINT no_null NOT NULL,
+ name varchar(40) NOT NULL
+);
+
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40) UNIQUE
+);
+
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name)
+);
+
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name) WITH (fillfactor=70)
+)
+WITH (fillfactor=70);
+-- 90 STATEMENTS *******************************************************
+CREATE TABLE cinemas (
+ id serial,
+ name text,
+ location text
+) TABLESPACE diskvol1;
+
+--CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name
+-- [ (column_name [, ...] ) ]
+-- [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+-- [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+-- [ TABLESPACE tablespace ]
+-- AS query
+-- [ WITH [ NO ] DATA ]
+
+CREATE TABLE films_recent AS
+ SELECT * FROM films WHERE date_prod >= '2002-01-01';
+
+CREATE TABLE films2 AS
+ TABLE films;
+
+CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
+ EXECUTE recentfilms('2002-01-01');
+
+--CREATE TABLESPACE tablespacename [ OWNER username ] LOCATION 'directory '
+
+CREATE TABLESPACE dbspace LOCATION '/data/dbs';
+
+CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
+
+--CREATE TEXT SEARCH CONFIGURATION name (
+-- PARSER = parser_name |
+-- COPY = source_config
+--)
+
+CREATE TEXT SEARCH CONFIGURATION my_search_config (
+ PARSER = my_parser
+);
+
+--CREATE TEXT SEARCH DICTIONARY name (
+-- TEMPLATE = template
+-- [, option = value [, ... ]]
+--)
+
+CREATE TEXT SEARCH DICTIONARY my_russian (
+ template = snowball,
+ language = russian,
+ stopwords = myrussian
+);
+
+--CREATE TEXT SEARCH PARSER name (
+-- START = start_function ,
+-- GETTOKEN = gettoken_function ,
+-- END = end_function ,
+-- LEXTYPES = lextypes_function
+-- [, HEADLINE = headline_function ]
+--)
+
+CREATE TEXT SEARCH PARSER my_search_parser (
+ START = startNow(),
+ GETTOKEN = getToken(),
+ END = end(),
+ LEXTYPES = getLexTypes()
+);
+
+--CREATE TEXT SEARCH TEMPLATE name (
+-- [ INIT = init_function , ]
+-- LEXIZE = lexize_function
+--)
+
+CREATE TEXT SEARCH TEMPLATE my_search_template (
+ LEXIZE = lexizeNow()
+);
+
+--CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }
+-- ON table [ FOR [ EACH ] { ROW | STATEMENT } ]
+-- EXECUTE PROCEDURE funcname ( arguments )
+-- 100 STATEMENTS *******************************************************
+CREATE TRIGGER trigger_name BEFORE dawn
+ ON table
+ EXECUTE PROCEDURE funcname ( 'arg1', 'arg2' );
+
+ALTER TABLE foreign_companies RENAME COLUMN address TO city;
+
+ALTER TABLE us_companies RENAME TO suppliers;
+
+ALTER TABLE old_addresses ALTER COLUMN street SET NOT NULL;
+
+ALTER TABLE new_addresses ALTER COLUMN street DROP NOT NULL;
+
+GRANT EXECUTE ON FUNCTION divideByTwo(numerator int, IN demoninator int) TO george;
+
+-- 106 STATEMENTS *******************************************************
View
7 modeshape-ddl-parser-example/src/test/resources/revoke_test_statements.ddl
@@ -0,0 +1,7 @@
+REVOKE SELECT ON TABLE purchaseOrders FROM maria,harry;
+
+REVOKE UPDATE, USAGE ON TABLE orderDetails FROM anita,zhi CASCADE;
+
+REVOKE SELECT ON TABLE orders.bills FROM PUBLIC RESTRICT;
+
+REVOKE INSERT(a, b, c) ON TABLE orderSummaries FROM purchases_reader_role;
View
103 modeshape-ddl-parser-example/src/test/resources/standard_test_statements.ddl
@@ -0,0 +1,103 @@
+CREATE SCHEMA AUTHORIZATION oe
+ CREATE TABLE new_product
+ (color VARCHAR(10) PRIMARY KEY, quantity NUMERIC)
+ CREATE VIEW new_product_view
+ AS SELECT color, quantity FROM new_product WHERE color = 'RED'
+ GRANT select ON new_product_view TO hr;
+
+CREATE SCHEMA schema_name_1
+ CREATE TABLE table_name_15 (
+ column_name_1 VARCHAR(255)
+ REFERENCES ref_table_name (ref_column_name_1)
+ ON UPDATE NO ACTION )
+ CREATE VIEW SAMP.V1 (COL_SUM, COL_DIFF)
+ AS SELECT COMM + BONUS, COMM - BONUS
+ FROM SAMP.EMPLOYEE
+ CREATE TABLE table_name26 (
+ column_name_1 VARCHAR(255),
+ UNIQUE (ref_column_name_1));
+
+CREATE TABLE MORE_ACTIVITIES (CITY_ID INT NOT NULL,
+ SEASON VARCHAR(20), ACTIVITY VARCHAR(32) NOT NULL);
+
+CREATE TABLE PEOPLE
+ (PERSON_ID INT NOT NULL CONSTRAINT PEOPLE_PK PRIMARY KEY, PERSON VARCHAR(26));
+
+CREATE TABLE table_name29 (
+ column_name_1 VARCHAR(255),
+ CONSTRAINT fk_name FOREIGN KEY (ref_column_name_1, ref_column_name_2)
+ REFERENCES ref_table_name (ref_column_name_1)
+ ON DELETE CASCADE ON UPDATE SET NULL
+ MATCH FULL);
+
+CREATE TABLE ACTIVITIES (CITY_ID INT NOT NULL,
+ SEASON VARCHAR(20), ACTIVITY VARCHAR(32) NOT NULL)
+
+CREATE TABLE HOTELAVAILABILITY
+ (HOTEL_ID INT NOT NULL, BOOKING_DATE DATE NOT NULL,
+ ROOMS_TAKEN INT DEFAULT 0, PRIMARY KEY (HOTEL_ID, BOOKING_DATE));
+
+CREATE TABLE employee (
+ empno NUMBER(4) NOT NULL,
+ empname CHAR(10),
+ job CHAR(9),
+ deptno NUMBER(2) NOT NULL,
+ CONSTRAINT emp_fk1 FOREIGN KEY (deptno) REFERENCES dept (deptno) INITIALLY IMMEDIATE,
+ CONSTRAINT emp_pk PRIMARY KEY (empno));
+
+CREATE ASSERTION assertNotNull CHECK (value != null) NOT DEFERRABLE;
+
+CREATE ASSERTION assertIsZero CHECK (value != null and value == 0) INITIALLY DEFERRED;
+
+CREATE ASSERTION Avgs CHECK( 3.0 < (SELECT avg(GPA) FROM Student) AND 1000 > (SELECT avg(sizeHS) FROM Student));
+
+CREATE DOMAIN full_domain CHAR DEFAULT null;
+
+CREATE DOMAIN partial_domain AS INTEGER DEFAULT (25);
+
+create domain mydecimal decimal(10) default 1 check (mydecimal>=0) initially immediate not deferrable;
+create domain myinteger as integer constraint myintegconstr1 check(myinteger is not null);
+create domain mynchar as nchar(100) collate schema1.collation2;
+create character set cs1 get WIN1250 collation from desc(collation1);
+create character set cs2 as get unicode collate collation2;
+create character set cs3 as get WIN1250;
+create character set cs4 get WIN1250 collation from external('externcollat2');
+create character set cs5 get WIN1250 collation from translation tn1 then collation collation1;
+create collation collation1 for cs1 from default no pad;
+create collation collation2 for cs2 from translation tn1 then collation collation1;
+create collation collation3 for cs3 from external('externcollat2') pad space;
+create translation tn1 for cs1 to cs2 from external('externtransl2');
+create translation tn2 for cs2 to cs3 from identity;
+create translation tn3 for cs3 to cs4 from tn2;
+create assertion assertconstr1 check(1=(select count(*) from a)) initially immediate not deferrable;
+create assertion assertconstr2 check((select max(b) from c)>0);
+
+create schema schema_1 authorization ADM default character set UNICODE
+ create table table_1 (col1 varchar(20) not null, col2 nchar default current_user)
+ create view view_1 (col1, col2) as select*from a with check option
+;
+create schema schema_2;
+create global temporary table table_3 (col1 dec(10,2) default 0) on commit delete rows;
+create local temporary table table_4 (col1 dec default null primary key) on commit preserve rows;
+create table table_5 (
+ col1 integer unique, col2 smallint unique,
+ col3 numeric(5,0) references table_3(col1) match full on delete cascade,
+ col4 numeric(5,0) references table_4(col1) match partial on delete set default on update set null,
+ col5 numeric(5,0) references table_1(col1) on update no action on delete cascade check (col5<col4),
+ col6 date not null check (col5<col4 and col6<=date'2003-12-31') unique,
+ unique (col1,col4) initially immediate not deferrable,
+ constraint pk5 primary key (col1) initially deferred,
+ foreign key (col4,col5) references table_7(col2,col3) not deferrable initially immediate,
+ constraint ck2 check (col5 is not null)
+);
+create view view_1 (col1,col2) as values (1,2);
+create view view_1 (col1,col2) as values (1,2) with check option;
+create view view_1 (col1,col2) as select a,b from c with local check option;
+create view view_1 (col1,col2) as table c with cascaded check option;
+grant all privileges on table_1 to public with grant option;
+grant delete,insert(col1,col2),update, references on table table_1 to user1, user1;
+grant usage on domain dom1 to user3;
+grant usage on collation col1 to user4, user5;
+grant usage on character set cs1 to user6;
+grant usage on translation tn1 to user7;
+
View
43 ...shape-embedded-example/src/main/java/org/modeshape/example/embedded/ModeShapeExample.java
@@ -2,32 +2,32 @@
import java.io.IOException;
import java.net.URL;
-import javax.jcr.Repository;
-import javax.jcr.Session;
import javax.jcr.Node;
+import javax.jcr.Repository;
import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import org.modeshape.jcr.JcrConfiguration;
import org.modeshape.jcr.JcrEngine;
import org.xml.sax.SAXException;
public class ModeShapeExample {
-
- public static void main( String[] argv ) {
-
- // Load the configuration via the classloader (can also use path to a file)...
- JcrConfiguration config = new JcrConfiguration();
+
+ public static void main( String[] argv ) {
+
+ // Load the configuration via the classloader (can also use path to a file)...
+ JcrConfiguration config = new JcrConfiguration();
try {
- URL url = ModeShapeExample.class.getClassLoader().getResource("modeshape-config.xml");
- config.loadFrom(url);
- } catch ( SAXException e ) {
+ URL url = ModeShapeExample.class.getClassLoader().getResource("modeshape-config.xml");
+ config.loadFrom(url);
+ } catch (SAXException e) {
System.err.println("Failed to read the configuration file");
- } catch ( IOException e ) {
+ } catch (IOException e) {
System.err.println("Failed to load the configuration file");
}
-
- // Create and start the engine ...
+
+ // Create and start the engine ...
JcrEngine engine = config.build();
- if ( engine.getProblems().hasErrors() ) {
+ if (engine.getProblems().hasErrors()) {
System.err.println("Problems starting the engine.");
System.err.println(engine.getProblems());
System.exit(-1);
@@ -39,22 +39,23 @@ public static void main( String[] argv ) {
Repository repository = null;
Session session = null;
try {
- // Get the repository
+ // Get the repository
repository = engine.getRepository("My repository");
- // Create a session ...
+ // Create a session ...
session = repository.login("default");
// Get the root node ...
Node root = session.getRootNode();
-
+ assert root != null;
+
System.out.println("Found the root node in the \"" + session.getWorkspace().getName() + "\" workspace");
- } catch ( RepositoryException e ) {
+ } catch (RepositoryException e) {
System.err.println("Failed to load the configuration file");
} finally {
- if ( session != null ) session.logout();
- if ( engine != null ) engine.shutdown();
+ if (session != null) session.logout();
+ engine.shutdown();
}
- }
+ }
}
View
1 pom.xml
@@ -15,5 +15,6 @@
</scm>
<modules>
<module>modeshape-embedded-example</module>
+ <module>modeshape-ddl-parser-example</module>
</modules>
</project>

0 comments on commit dc69252

Please sign in to comment.
Something went wrong with that request. Please try again.