[teiid-commits] teiid SVN: r4201 - in trunk: api/src/main/java/org/teiid/language and 6 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Fri Jun 22 17:11:14 EDT 2012


Author: rareddy
Date: 2012-06-22 17:11:13 -0400 (Fri, 22 Jun 2012)
New Revision: 4201

Added:
   trunk/engine/src/main/java/org/teiid/query/metadata/DDLConstants.java
   trunk/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java
   trunk/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java
Modified:
   trunk/admin/src/main/java/org/teiid/adminapi/Admin.java
   trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java
   trunk/api/src/main/java/org/teiid/language/SQLConstants.java
   trunk/jboss-integration/src/main/java/org/teiid/jboss/OperationsConstants.java
   trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidExtension.java
   trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java
   trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
   trunk/jboss-integration/src/test/java/org/teiid/jboss/TestTeiidConfiguration.java
   trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestDeployment.java
Log:
TEIID-2083: Adding a way export the metadata of the vdb's model using DDL. This operation can e invoked through CLI or admin methods.

Modified: trunk/admin/src/main/java/org/teiid/adminapi/Admin.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/Admin.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/admin/src/main/java/org/teiid/adminapi/Admin.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -24,6 +24,7 @@
 
 import java.io.InputStream;
 import java.util.Collection;
+import java.util.EnumSet;
 import java.util.Properties;
 import java.util.Set;
 
@@ -32,6 +33,8 @@
 public interface Admin {
 
 	public enum Cache {PREPARED_PLAN_CACHE, QUERY_SERVICE_RESULT_SET_CACHE};
+	
+	public enum SchemaObjectType {TABLES, PROCEDURES, FUNCTIONS};
     
     /**
      * Assign a {@link Translator} and Data source to a {@link VDB}'s Model
@@ -292,5 +295,16 @@
      * @param jndiName
      * @throws AdminException
      */
-    void markDataSourceAvailable(String jndiName) throws AdminException;    
+    void markDataSourceAvailable(String jndiName) throws AdminException;
+    
+    /**
+     * Retrieve the schema of the given model
+     *  
+     * @param vdbName
+     * @param vdbVersion
+     * @param modelName
+     * @param EnumSet<SchemaObjectType> Type of schema objects to retrieve, null means ALL the schema object types
+     * @param typeNamePattern RegEx pattern to filter to names of tables, procedures that are being read. Null means no filter.  
+     */
+    String getSchema(String vdbName, int vdbVersion, String modelName, EnumSet<SchemaObjectType> allowedTypes, String typeNamePattern) throws AdminException;
 }

Modified: trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -22,7 +22,9 @@
 
 package org.teiid.adminapi;
 
-import static org.jboss.as.controller.client.helpers.ClientConstants.*;
+import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_REMOVE_OPERATION;
+import static org.jboss.as.controller.client.helpers.ClientConstants.DEPLOYMENT_UNDEPLOY_OPERATION;
+import static org.jboss.as.controller.client.helpers.ClientConstants.RESULT;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -32,11 +34,7 @@
 import java.util.*;
 import java.util.logging.Logger;
 
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.*;
 import javax.security.sasl.RealmCallback;
 import javax.security.sasl.RealmChoiceCallback;
 
@@ -49,12 +47,7 @@
 import org.jboss.dmr.ModelType;
 import org.teiid.adminapi.PropertyDefinition.RestartType;
 import org.teiid.adminapi.VDB.ConnectionType;
-import org.teiid.adminapi.impl.AdminObjectImpl;
-import org.teiid.adminapi.impl.MetadataMapper;
-import org.teiid.adminapi.impl.PropertyDefinitionMetadata;
-import org.teiid.adminapi.impl.VDBMetaData;
-import org.teiid.adminapi.impl.VDBMetadataMapper;
-import org.teiid.adminapi.impl.VDBTranslatorMetaData;
+import org.teiid.adminapi.impl.*;
 import org.teiid.adminapi.impl.VDBMetadataMapper.RequestMetadataMapper;
 import org.teiid.adminapi.impl.VDBMetadataMapper.SessionMetadataMapper;
 import org.teiid.adminapi.impl.VDBMetadataMapper.TransactionMetadataMapper;
@@ -1337,6 +1330,50 @@
 	        } catch (Exception e) {
 	        	 throw new AdminProcessingException(AdminPlugin.Event.TEIID70046, e);
 	        }		        
+		}
+
+		@Override
+		public String getSchema(String vdbName, int vdbVersion,
+				String modelName, EnumSet<SchemaObjectType> allowedTypes,
+				String typeNamePattern) throws AdminException {
+			ModelNode request = null;
+			
+			ArrayList<String> params = new ArrayList<String>();
+			params.add("vdb-name");
+			params.add(vdbName);
+			params.add("vdb-version");
+			params.add(String.valueOf(vdbVersion));
+			params.add("model-name");
+			params.add(modelName);
+			
+			if (allowedTypes != null) {
+				params.add("entity-type");
+				StringBuilder sb = new StringBuilder();
+				for (SchemaObjectType type:allowedTypes) {
+					if (sb.length() > 0) {
+						sb.append(",");
+					}
+					sb.append(type.name());
+				}
+				params.add(sb.toString());
+			}
+			
+			if (typeNamePattern != null) {
+				params.add("entity-pattern");
+				params.add(typeNamePattern);
+			}
+			
+			request = buildRequest("teiid", "get-schema", params.toArray(new String[params.size()]));//$NON-NLS-1$ //$NON-NLS-2$
+			
+	        try {
+	            ModelNode outcome = this.connection.execute(request);
+	            if (!Util.isSuccess(outcome)) {
+	            	 throw new AdminProcessingException(AdminPlugin.Event.TEIID70045, Util.getFailureDescription(outcome));
+	            }
+	            return outcome.get(RESULT).asString();
+	        } catch (Exception e) {
+	        	 throw new AdminProcessingException(AdminPlugin.Event.TEIID70046, e);
+	        }
 		}		
     }
 }

Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -47,6 +47,8 @@
 		public static final String LPAREN = "("; //$NON-NLS-1$
 		public static final String RPAREN = ")"; //$NON-NLS-1$
 		public static final String COLON = ":"; //$NON-NLS-1$
+		public static final String TICK = "'"; //$NON-NLS-1$
+		public static final String SEMICOLON = ";"; //$NON-NLS-1$
 	}
 	
 	public interface NonReserved {

Added: trunk/engine/src/main/java/org/teiid/query/metadata/DDLConstants.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/DDLConstants.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/DDLConstants.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -0,0 +1,77 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * 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.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it 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.
+ * 
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.query.metadata;
+
+public interface DDLConstants {
+	public static final String JAVA_METHOD = "JAVA_METHOD";//$NON-NLS-1$
+	public static final String JAVA_CLASS = "JAVA_CLASS";//$NON-NLS-1$
+	public static final String DETERMINISM = "DETERMINISM";//$NON-NLS-1$
+	public static final String CATEGORY = "CATEGORY";//$NON-NLS-1$
+	public static final String FUNCTION2 = "FUNCTION";//$NON-NLS-1$
+	public static final String OUT = "OUT";//$NON-NLS-1$
+	public static final String INOUT = "INOUT";//$NON-NLS-1$
+	public static final String IN = "IN";//$NON-NLS-1$
+	public static final String UPDATECOUNT = "UPDATECOUNT";//$NON-NLS-1$
+	public static final String RETURNS = "RETURNS";//$NON-NLS-1$
+	public static final String PROCEDURE2 = "PROCEDURE";//$NON-NLS-1$
+	public static final String FOREIGN = "FOREIGN";//$NON-NLS-1$
+	public static final String VIRTUAL = "VIRTUAL";//$NON-NLS-1$
+	public static final String DISTINCT_VALUES = "DISTINCT_VALUES";//$NON-NLS-1$
+	public static final String NULL_VALUE_COUNT = "NULL_VALUE_COUNT";//$NON-NLS-1$
+	public static final String RADIX = "RADIX";//$NON-NLS-1$
+	public static final String NATIVE_TYPE = "NATIVE_TYPE";//$NON-NLS-1$
+	public static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH";//$NON-NLS-1$
+	public static final String MAX_VALUE = "MAX_VALUE"; //$NON-NLS-1$
+	public static final String MIN_VALUE = "MIN_VALUE";//$NON-NLS-1$
+	public static final String SEARCHABLE = "SEARCHABLE";//$NON-NLS-1$
+	public static final String FIXED_LENGTH = "FIXED_LENGTH";//$NON-NLS-1$
+	public static final String CURRENCY = "CURRENCY";//$NON-NLS-1$
+	public static final String SIGNED = "SIGNED";//$NON-NLS-1$
+	public static final String SELECTABLE = "SELECTABLE";//$NON-NLS-1$
+	public static final String CASE_SENSITIVE = "CASE_SENSITIVE";//$NON-NLS-1$
+	public static final String DEFAULT = "DEFAULT";//$NON-NLS-1$
+	public static final String AUTO_INCREMENT = "AUTO_INCREMENT";//$NON-NLS-1$
+	public static final String NOT_NULL = "NOT NULL";//$NON-NLS-1$
+	public static final String REFERENCES = "REFERENCES";//$NON-NLS-1$
+	public static final String FOREIGN_KEY = "FOREIGN KEY";//$NON-NLS-1$
+	public static final String INDEX = "INDEX";//$NON-NLS-1$
+	public static final String UNIQUE = "UNIQUE";//$NON-NLS-1$
+	public static final String PRIMARY_KEY = "PRIMARY KEY";//$NON-NLS-1$
+	public static final String ACCESSPATTERN = "ACCESSPATTERN";//$NON-NLS-1$
+	public static final String NAMEINSOURCE = "NAMEINSOURCE";//$NON-NLS-1$
+	public static final String ANNOTATION = "ANNOTATION";//$NON-NLS-1$
+	public static final String UUID = "UUID";//$NON-NLS-1$
+	public static final String CARDINALITY = "CARDINALITY";//$NON-NLS-1$
+	public static final String UPDATABLE = "UPDATABLE";//$NON-NLS-1$
+	public static final String MATERIALIZED_TABLE = "MATERIALIZED_TABLE";//$NON-NLS-1$
+	public static final String MATERIALIZED = "MATERIALIZED";//$NON-NLS-1$
+	public static final String INSTEAD_OF = "INSTEAD OF";//$NON-NLS-1$
+	public static final String CREATE_TRIGGER_ON = "CREATE TRIGGER ON";//$NON-NLS-1$
+	public static final String DELETE = "DELETE";//$NON-NLS-1$
+	public static final String UPDATE = "UPDATE";//$NON-NLS-1$
+	public static final String INSERT = "INSERT";//$NON-NLS-1$
+	public static final String OPTIONS2 = "OPTIONS";//$NON-NLS-1$
+	public static final String CONSTRAINT = "CONSTRAINT";//$NON-NLS-1$
+	public static final String VIEW = "VIEW";//$NON-NLS-1$
+	public static final String FOREIGN_TABLE = "FOREIGN TABLE";//$NON-NLS-1$
+	public static final String CREATE = "CREATE";//$NON-NLS-1$
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/metadata/DDLConstants.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java	                        (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -0,0 +1,642 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * 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.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it 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.
+ * 
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.query.metadata;
+
+import static org.teiid.language.SQLConstants.Tokens.COMMA;
+import static org.teiid.language.SQLConstants.Tokens.LPAREN;
+import static org.teiid.language.SQLConstants.Tokens.RPAREN;
+import static org.teiid.language.SQLConstants.Tokens.SPACE;
+import static org.teiid.language.SQLConstants.Tokens.TICK;
+import static org.teiid.query.metadata.DDLConstants.*;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import org.teiid.adminapi.Admin.SchemaObjectType;
+import org.teiid.language.SQLConstants;
+import org.teiid.metadata.AbstractMetadataRecord;
+import org.teiid.metadata.BaseColumn.NullType;
+import org.teiid.metadata.Column;
+import org.teiid.metadata.ColumnSet;
+import org.teiid.metadata.ForeignKey;
+import org.teiid.metadata.FunctionMethod;
+import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.FunctionParameter;
+import org.teiid.metadata.KeyRecord;
+import org.teiid.metadata.Procedure;
+import org.teiid.metadata.ProcedureParameter;
+import org.teiid.metadata.ProcedureParameter.Type;
+import org.teiid.metadata.Schema;
+import org.teiid.metadata.Table;
+
+public class DDLStringVisitor {
+	private static final String TAB = "\t"; //$NON-NLS-1$
+	private static final String NEWLINE = "\n";//$NON-NLS-1$
+
+	protected StringBuilder buffer = new StringBuilder();
+	private boolean includeTables = true;
+	private boolean includeProcedures = true;
+	private boolean includeFunctions = true;
+	private String filter;
+	
+    public static String getDDLString(Schema schema, EnumSet<SchemaObjectType> types, String regexPattern) {
+    	DDLStringVisitor visitor = new DDLStringVisitor(types, regexPattern);
+        visitor.visit(schema);
+        return visitor.toString();
+    }
+	
+    public DDLStringVisitor(EnumSet<SchemaObjectType> types, String regexPattern) {
+    	if (types != null) {
+    		this.includeTables = types.contains(SchemaObjectType.TABLES);
+    		this.includeProcedures = types.contains(SchemaObjectType.PROCEDURES);
+    		this.includeFunctions = types.contains(SchemaObjectType.FUNCTIONS);
+    	}
+    	this.filter = regexPattern;
+    }
+    
+	private void visit(Schema schema) {
+		boolean first = true; 
+		
+		if (this.includeTables) {
+			for (Table t: schema.getTables().values()) {
+				if (first) {
+					first = false;
+				}
+				else {
+					buffer.append(NEWLINE);
+					buffer.append(NEWLINE);
+				}			
+				visit(t);
+			}
+		}
+		
+		if (this.includeProcedures) {
+			for (Procedure p:schema.getProcedures().values()) {
+				if (first) {
+					first = false;
+				}
+				else {
+					buffer.append(NEWLINE);
+					buffer.append(NEWLINE);
+				}				
+				visit(p);
+			}
+		}
+		
+		if (this.includeFunctions) {
+			for (FunctionMethod f:schema.getFunctions().values()) {
+				if (first) {
+					first = false;
+				}
+				else {
+					buffer.append(NEWLINE);
+					buffer.append(NEWLINE);
+				}				
+				visit(f);
+			}
+		}
+	}
+
+	private void visit(Table table) {
+		if (this.filter != null && !table.getName().matches(this.filter)) {
+			return;
+		}
+		
+		buffer.append(CREATE).append(SPACE);
+		if (table.isPhysical()) {
+			buffer.append(FOREIGN_TABLE);
+		}
+		else {
+			buffer.append(VIEW);
+		}
+		buffer.append(SPACE);
+		buffer.append(table.getName());
+		
+		if (table.getColumns() != null) {
+			buffer.append(SPACE);
+			buffer.append(LPAREN);
+			boolean first = true; 
+			for (Column c:table.getColumns()) {
+				if (first) {
+					first = false;
+				}
+				else {
+					buffer.append(COMMA);
+				}
+				visit(c, table);
+			}
+			
+			// constraints
+			String contraints = buildContraints(table);
+			if (!contraints.isEmpty()) {
+				buffer.append(NEWLINE).append(TAB);
+				buffer.append(CONSTRAINT);
+				buffer.append(contraints);
+			}
+			buffer.append(NEWLINE);
+			buffer.append(RPAREN);			
+		}
+		
+		// options
+		String options = buildTableOptions(table);		
+		if (!options.isEmpty()) {
+			buffer.append(SPACE).append(OPTIONS2).append(SPACE).append(LPAREN).append(options).append(RPAREN);
+		}
+		
+		if (table.isVirtual()) {
+			buffer.append(NEWLINE).append(SQLConstants.Reserved.AS).append(NEWLINE).append(table.getSelectTransformation());
+		}
+		buffer.append(SQLConstants.Tokens.SEMICOLON);
+		
+		if (table.isInsertPlanEnabled()) {
+			buildTrigger(table.getName(), INSERT, table.getInsertPlan());
+		}
+		
+		if (table.isUpdatePlanEnabled()) {
+			buildTrigger(table.getName(), UPDATE, table.getUpdatePlan());
+		}	
+		
+		if (table.isDeletePlanEnabled()) {
+			buildTrigger(table.getName(), DELETE, table.getDeletePlan());
+		}			
+	}
+
+	private void buildTrigger(String name, String type, String plan) {
+		buffer.append(NEWLINE);
+		buffer.append(NEWLINE);
+		buffer.append(CREATE_TRIGGER_ON).append(SPACE);
+		buffer.append(name).append(SPACE).append(INSTEAD_OF).append(SPACE).append(type).append(SPACE).append(SQLConstants.Reserved.AS).append(NEWLINE);
+		buffer.append(plan);
+		buffer.append(SQLConstants.Tokens.SEMICOLON);
+	}
+
+	private String buildTableOptions(Table table) {
+		StringBuilder options = new StringBuilder();
+		addCommonOptions(options, table);
+		
+		if (table.isMaterialized()) {
+			addOption(options, MATERIALIZED, String.valueOf(table.isMaterialized()));
+			if (table.getMaterializedTable() != null) {
+				addOption(options, MATERIALIZED_TABLE, table.getMaterializedTable().getName());
+			}
+		}
+		if (table.supportsUpdate()) {
+			addOption(options, UPDATABLE, String.valueOf(table.supportsUpdate()));
+		}
+		if (table.getCardinality() != -1) {
+			addOption(options, CARDINALITY, table.getCardinality());
+		}
+		if (!table.getProperties().isEmpty()) {
+			for (String key:table.getProperties().keySet()) {
+				addOption(options, key, table.getProperty(key, false));
+			}
+		}
+		return options.toString();
+	}
+
+	private void addCommonOptions(StringBuilder sb, AbstractMetadataRecord record) {
+		if (record.getUUID() != null && !record.getUUID().startsWith("mmuuid:")) { //$NON-NLS-1$
+			addOption(sb, UUID, record.getUUID());
+		}
+		if (record.getAnnotation() != null) {
+			addOption(sb, ANNOTATION, record.getAnnotation());
+		}
+		if (record.getNameInSource() != null && !record.getNameInSource().equals(record.getName())) {
+			addOption(sb, NAMEINSOURCE, record.getNameInSource());
+		}
+	}
+	
+	private String buildContraints(Table table) {
+		StringBuilder options = new StringBuilder();
+		
+		boolean first = true;
+		for (KeyRecord key:table.getAccessPatterns()) {
+			if (first) {
+				first = false;
+			}
+			else {
+				options.append(COMMA);
+			}			
+			options.append(SPACE).append(ACCESSPATTERN);
+			addColumns(options, key.getColumns(), false);
+		}
+		
+		
+		KeyRecord pk = table.getPrimaryKey();
+		if (pk != null && pk.getColumns().size() > 1) {
+			if (first) {
+				first = false;
+			}
+			else {
+				options.append(COMMA);
+			}
+			options.append(SPACE).append(PRIMARY_KEY);
+			addColumns(options, pk.getColumns(), false);
+		}
+		
+		for (KeyRecord key:table.getUniqueKeys()) {
+			if (key != null && key.getColumns().size() > 1) {
+				if (first) {
+					first = false;
+				}
+				else {
+					options.append(COMMA);
+				}
+				options.append(SPACE).append(UNIQUE);
+				addColumns(options, key.getColumns(), false);
+			}
+		}
+		
+		for (KeyRecord key:table.getIndexes()) {
+			if (key != null && key.getColumns().size() > 1) {
+				if (first) {
+					first = false;
+				}
+				else {
+					options.append(COMMA);
+				}				
+				options.append(SPACE).append(INDEX);
+				addColumns(options, key.getColumns(), false);
+			}
+		}		
+
+		for (ForeignKey key:table.getForeignKeys()) {
+			if (first) {
+				first = false;
+			}
+			else {
+				options.append(COMMA);
+			}			
+			options.append(SPACE).append(FOREIGN_KEY);
+			addColumns(options, key.getColumns(), false);
+			options.append(SPACE).append(REFERENCES);
+			if (key.getReferenceTableName() != null) {
+				options.append(SPACE).append(key.getReferenceTableName());
+			}
+			options.append(SPACE);
+			addNames(options, key.getReferenceColumns());
+		}
+		
+		return options.toString();
+	}
+
+	private void addColumns(StringBuilder options, List<Column> columns, boolean includeType) {
+		options.append(LPAREN);
+		boolean first = true;
+		for (Column c:columns) {
+			if (first) {
+				first = false;
+			}
+			else {
+				options.append(COMMA).append(SPACE);
+			}
+			options.append(c.getName());
+			if (includeType) {
+				options.append(SPACE).append(c.getDatatype().getName());
+			}
+		}
+		options.append(RPAREN);
+	}
+	
+	private void addNames(StringBuilder options, List<String> columns) {
+		if (columns != null) {
+			options.append(LPAREN);
+			boolean first = true;
+			for (String c:columns) {
+				if (first) {
+					first = false;
+				}
+				else {
+					options.append(COMMA).append(SPACE);
+				}
+				options.append(c);
+			}
+			options.append(RPAREN);
+		}
+	}	
+	
+	private void visit(Column column, Table table) {
+		buffer.append(NEWLINE).append(TAB).append(column.getName()).append(SPACE).append(column.getDatatype().getName());
+		if (column.getLength() != 0) {
+			buffer.append(LPAREN).append(column.getLength()).append(RPAREN);
+		}
+		else if (column.getPrecision() != 0){
+			buffer.append(LPAREN).append(column.getPrecision());
+			if (column.getScale() != 0) {
+				buffer.append(COMMA).append(column.getScale());
+			}
+			buffer.append(RPAREN);
+		}
+		if (column.getNullType() != null) {
+			if (column.getNullType() == NullType.No_Nulls) {
+				buffer.append(SPACE).append(NOT_NULL);
+			}
+		}
+		
+		if (column.isAutoIncremented()) {
+			buffer.append(SPACE).append(AUTO_INCREMENT);
+		}
+		
+		KeyRecord pk = table.getPrimaryKey();
+		if (pk != null && pk.getColumns().size() == 1) {
+			Column c = pk.getColumns().get(0);
+			if (column.equals(c)) {
+				buffer.append(SPACE).append(PRIMARY_KEY);
+			}
+		}
+		
+		for (KeyRecord key:table.getUniqueKeys()) {
+			if (key != null && key.getColumns().size() == 1) {
+				Column c = key.getColumns().get(0);
+				if (column.equals(c)) {
+					buffer.append(SPACE).append(UNIQUE);
+				}
+			}
+		}
+		
+		for (KeyRecord key:table.getIndexes()) {
+			if (key != null && key.getColumns().size() == 1) {
+				Column c = key.getColumns().get(0);
+				if (column.equals(c)) {
+					buffer.append(SPACE).append(INDEX);
+				}
+			}
+		}		
+		
+		if (column.getDefaultValue() != null) {
+			buffer.append(SPACE).append(DEFAULT).append(SPACE).append(TICK).append(column.getDefaultValue()).append(TICK);
+		}
+		
+		// options
+		String options = buildColumnOptions(column, table);		
+		if (!options.isEmpty()) {
+			buffer.append(SPACE).append(OPTIONS2).append(SPACE).append(LPAREN).append(options).append(RPAREN);
+		}
+	}	
+	
+	private String buildColumnOptions(Column column, Table table) {
+		StringBuilder options = new StringBuilder();
+		addCommonOptions(options, column);
+		
+		if (column.isCaseSensitive()) {
+			addOption(options, CASE_SENSITIVE, String.valueOf(column.isCaseSensitive()));
+		}
+		
+		if (!column.isSelectable()) {
+			addOption(options, SELECTABLE, String.valueOf(column.isSelectable()));
+		}		
+
+		// if table is already updatable, then columns are implicitly updatable.
+		if (table.supportsUpdate() && !column.isUpdatable()) {
+			addOption(options, UPDATABLE, String.valueOf(column.isUpdatable()));
+		}
+		
+		if (column.isSigned()) {
+			addOption(options, SIGNED, String.valueOf(column.isSigned()));
+		}
+		
+		if (column.isCurrency()) {
+			addOption(options, CURRENCY, String.valueOf(column.isCurrency()));
+		}
+			
+		if (column.isFixedLength()) {
+			addOption(options, FIXED_LENGTH, String.valueOf(column.isFixedLength()));
+		}
+		
+		if (column.getSearchType() != null) {
+			addOption(options, SEARCHABLE, column.getSearchType().name());
+		}
+		
+		if (column.getMinimumValue() != null) {
+			addOption(options, MIN_VALUE, column.getMinimumValue());
+		}
+		
+		if (column.getMaximumValue() != null) {
+			addOption(options, MAX_VALUE, column.getMaximumValue());
+		}
+		
+		if (column.getCharOctetLength() != 0) {
+			addOption(options, CHAR_OCTET_LENGTH, column.getCharOctetLength());
+		}	
+		
+		// only set native type on the foreign tables, on view the data type is type
+		if (table.isPhysical() && column.getNativeType() != null) {
+			addOption(options, NATIVE_TYPE, column.getNativeType());
+		}
+		
+		if (column.getRadix() != 0) {
+			addOption(options, RADIX, column.getRadix());
+		}
+		if (column.getNullValues() != -1) {
+			addOption(options, NULL_VALUE_COUNT, column.getNullValues());
+		}
+		if (column.getDistinctValues() != -1) {
+			addOption(options, DISTINCT_VALUES, column.getDistinctValues());
+		}		
+		
+		if (!column.getProperties().isEmpty()) {
+			for (String key:column.getProperties().keySet()) {
+				addOption(options, key, column.getProperty(key, false));
+			}
+		}
+		return options.toString();
+	}	
+	
+	private void addOption(StringBuilder sb, String key, String value) {
+		if (sb.length() != 0) {
+			sb.append(COMMA).append(SPACE);
+		}
+		sb.append(key).append(SPACE).append(TICK).append(value).append(TICK);
+	}
+	
+	private void addOption(StringBuilder sb, String key, int value) {
+		if (sb.length() != 0) {
+			sb.append(COMMA).append(SPACE);
+		}		
+		sb.append(key).append(SPACE).append(value);
+	}	
+
+	private void visit(Procedure procedure) {
+		if (this.filter != null && !procedure.getName().matches(this.filter)) {
+			return;
+		}
+		
+		buffer.append(CREATE).append(SPACE);
+		if (procedure.isVirtual()) {
+			buffer.append(VIRTUAL);
+		}
+		else {
+			buffer.append(FOREIGN);
+		}
+		buffer.append(SPACE).append(PROCEDURE2).append(SPACE).append(procedure.getName());
+		buffer.append(LPAREN);
+		
+		boolean first = true;
+		for (ProcedureParameter pp:procedure.getParameters()) {
+			Type type = pp.getType();
+			if (type == Type.In || type == Type.InOut || type == Type.Out) {
+				if (first) {
+					first = false;
+				}
+				else {
+					buffer.append(COMMA).append(SPACE);
+				}
+				visit(pp);
+			}
+		}
+		buffer.append(RPAREN);
+		
+		buffer.append(SPACE).append(RETURNS).append(SPACE);
+		buildProcedureReturn(procedure.getResultSet(), procedure.getParameters());
+		
+		//options
+		String options = buildProcedureOptions(procedure);		
+		if (!options.isEmpty()) {
+			buffer.append(NEWLINE).append(OPTIONS2).append(SPACE).append(LPAREN).append(options).append(RPAREN);
+		}		
+		//block
+		if (procedure.isVirtual()) {
+			buffer.append(NEWLINE).append(SQLConstants.Reserved.AS).append(NEWLINE);
+			String plan = procedure.getQueryPlan();
+			buffer.append(plan.substring("CREATE VIRTUAL PROCEDURE BEGIN ".length(), plan.length()-"END".length())); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+
+	private String buildProcedureOptions(Procedure procedure) {
+		StringBuilder options = new StringBuilder();
+		addCommonOptions(options, procedure);
+		
+		if (procedure.getUpdateCount() != 1) {
+			addOption(options, UPDATECOUNT, procedure.getUpdateCount());
+		}	
+		
+		if (!procedure.getProperties().isEmpty()) {
+			for (String key:procedure.getProperties().keySet()) {
+				addOption(options, key, procedure.getProperty(key, false));
+			}
+		}		
+		
+		return options.toString();
+	}
+
+	private void buildProcedureReturn(ColumnSet<Procedure> resultSet, List<ProcedureParameter> parameters) {
+		if (resultSet != null) {
+			addColumns(buffer, resultSet.getColumns(), true);
+		}
+		else {
+			if (parameters != null) {
+				for (ProcedureParameter pp: parameters) {
+					if (pp.getType().equals(Type.ReturnValue)) {
+						buffer.append(pp.getDatatype().getName());
+					}
+				}
+			}
+		}
+		
+	}
+	
+	private void visit(ProcedureParameter param) {
+		Type type = param.getType();
+		if (type == Type.In || type == Type.InOut || type == Type.Out) {
+			String typeStr = null;
+			if (type == Type.In) typeStr = IN;
+			if (type == Type.InOut) typeStr = INOUT;
+			if (type == Type.Out) typeStr = OUT;
+			buffer.append(typeStr).append(SPACE).append(param.getName()).append(SPACE).append(param.getDatatype().getName());
+		}
+	}	
+
+	private void visit(FunctionMethod function) {
+		if (this.filter != null && !function.getName().matches(this.filter)) {
+			return;
+		}		
+		buffer.append(CREATE).append(SPACE);
+		if (function.getPushdown().equals(FunctionMethod.PushDown.MUST_PUSHDOWN)) {
+			buffer.append(FOREIGN);
+		}
+		else {
+			buffer.append(VIRTUAL);
+		}
+		buffer.append(SPACE).append(FUNCTION2).append(SPACE).append(function.getName());
+		buffer.append(LPAREN);
+		
+		boolean first = true;
+		for (FunctionParameter fp:function.getInputParameters()) {
+			if (first) {
+				first = false;
+			}
+			else {
+				buffer.append(COMMA).append(SPACE);
+			}
+			visit(fp);
+		}
+		buffer.append(RPAREN);
+		
+		buffer.append(SPACE).append(RETURNS).append(SPACE);
+		buffer.append(function.getOutputParameter().getType());
+		
+		//options
+		String options = buildFunctionOptions(function);		
+		if (!options.isEmpty()) {
+			buffer.append(NEWLINE).append(OPTIONS2).append(SPACE).append(LPAREN).append(options).append(RPAREN);
+		}		
+		buffer.append(SQLConstants.Tokens.SEMICOLON);		
+	}
+
+	private String buildFunctionOptions(FunctionMethod function) {
+		StringBuilder options = new StringBuilder();
+		addCommonOptions(options, function);
+		
+		if (function.getCategory() != null) {
+			addOption(options, CATEGORY, function.getCategory());
+		}	
+		
+		if (!function.getDeterminism().equals(Determinism.DETERMINISTIC)) {
+			addOption(options, DETERMINISM, function.getDeterminism().name());
+		}		
+		
+		if (function.getInvocationClass() != null) {
+			addOption(options, JAVA_CLASS, function.getInvocationClass());
+		}
+
+		if (function.getInvocationMethod() != null) {
+			addOption(options, JAVA_METHOD, function.getInvocationMethod());
+		}
+		
+		if (!function.getProperties().isEmpty()) {
+			for (String key:function.getProperties().keySet()) {
+				addOption(options, key, function.getProperty(key, false));
+			}
+		}		
+		
+		return options.toString();
+	}
+
+	private void visit(FunctionParameter param) {
+		buffer.append(param.getName()).append(SPACE).append(param.getType());
+	}
+
+    public String toString() {
+        return buffer.toString();
+    }
+}


Property changes on: trunk/engine/src/main/java/org/teiid/query/metadata/DDLStringVisitor.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java	                        (rev 0)
+++ trunk/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -0,0 +1,247 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * 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.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it 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.
+ * 
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+package org.teiid.query.metadata;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.teiid.metadata.BaseColumn.NullType;
+import org.teiid.metadata.Column;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.Schema;
+import org.teiid.metadata.Table;
+import org.teiid.query.parser.ParseException;
+import org.teiid.query.parser.TestDDLParser;
+
+ at SuppressWarnings("nls")
+public class TestDDLStringVisitor {
+
+	@Test
+	public void testForeignTable() throws Exception {
+		
+		String ddl = "CREATE FOREIGN TABLE G1 (\n" + 
+				"	e1 integer PRIMARY KEY,\n" + 
+				"	e2 string(10) UNIQUE,\n" + 
+				"	e3 date NOT NULL UNIQUE,\n" + 
+				"	e4 bigdecimal(12,3),\n" + 
+				"	e5 integer AUTO_INCREMENT INDEX OPTIONS (UUID 'uuid', NAMEINSOURCE 'nis', SELECTABLE 'false'),\n" + 
+				"	e6 string INDEX DEFAULT 'hello'\n" + 
+				") OPTIONS (ANNOTATION 'Test Table', CARDINALITY '12', FOO 'BAR', UPDATABLE 'true', UUID 'uuid2');";
+		
+		MetadataFactory mf = new MetadataFactory("test", 1, "model", TestDDLParser.getDataTypes(), new Properties(), null);
+		
+		Table table = mf.addTable("G1");
+		table.setVirtual(false);
+		
+		mf.addColumn("e1","integer", table);
+		Column e2 = mf.addColumn("e2","varchar", table);
+		e2.setLength(10);
+		
+		Column e3 = mf.addColumn("e3","date", table);
+		e3.setNullType(NullType.No_Nulls);
+		
+		Column e4 = mf.addColumn("e4","decimal", table);
+		e4.setPrecision(12);
+		e4.setScale(3);
+		
+		Column e5 = mf.addColumn("e5","integer", table);
+		e5.setAutoIncremented(true);
+		e5.setUUID("uuid");
+		e5.setNameInSource("nis");
+		e5.setSelectable(false);
+		
+		Column e6 = mf.addColumn("e6","varchar", table);
+		e6.setDefaultValue("hello");
+		
+		mf.addPrimaryKey("PK", Arrays.asList("e1"), table);
+		mf.addIndex("UK", false, Arrays.asList("e2"), table);
+		mf.addIndex("UK2", false, Arrays.asList("e3"), table);
+		mf.addIndex("IDX", true, Arrays.asList("e5"), table);
+		mf.addIndex("IDX2", true, Arrays.asList("e6"), table);
+		
+		Map<String, String> options = new HashMap<String, String>();
+		options.put("CARDINALITY", "12");
+		options.put("UUID", "uuid2");
+		options.put("UPDATABLE", "true");
+		options.put("FOO", "BAR");
+		options.put("ANNOTATION", "Test Table");
+		table.setProperties(options);
+		
+		String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null);
+		assertEquals(ddl, metadataDDL);
+	}
+	
+	@Test
+	public void testMultiKeyPK() throws Exception {
+		String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date CONSTRAINT PRIMARY KEY (e1, e2))";
+		String expected = "CREATE FOREIGN TABLE G1 (\n" + 
+				"	e1 integer,\n" + 
+				"	e2 string,\n" + 
+				"	e3 date\n" + 
+				"	CONSTRAINT PRIMARY KEY(e1, e2)\n" + 
+				");";
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testConstraints2() throws Exception {
+		String ddl = "CREATE FOREIGN TABLE G1( e1 integer, e2 varchar, e3 date CONSTRAINT " +
+				"ACCESSPATTERN(e1), UNIQUE(e1), ACCESSPATTERN(e2, e3))";
+		String expected = "CREATE FOREIGN TABLE G1 (\n" + 
+				"	e1 integer UNIQUE,\n" + 
+				"	e2 string,\n" + 
+				"	e3 date\n" + 
+				"	CONSTRAINT ACCESSPATTERN(e1), ACCESSPATTERN(e2, e3)\n" + 
+				");";
+		helpTest(ddl, expected);
+	}		
+	
+	@Test
+	public void testFK() throws Exception {
+		String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar CONSTRAINT PRIMARY KEY(g1e1, g1e2));\n" +
+				"CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar CONSTRAINT " +
+				"FOREIGN KEY (g2e1, g2e2) REFERENCES G1 (g1e1, g1e2))";
+		
+		String expected = "CREATE FOREIGN TABLE G1 (\n" + 
+				"	g1e1 integer,\n" + 
+				"	g1e2 string\n" + 
+				"	CONSTRAINT PRIMARY KEY(g1e1, g1e2)\n" + 
+				");\n" + 
+				"\n" + 
+				"CREATE FOREIGN TABLE G2 (\n" + 
+				"	g2e1 integer,\n" + 
+				"	g2e2 string\n" + 
+				"	CONSTRAINT FOREIGN KEY(g2e1, g2e2) REFERENCES G1 (g1e1, g1e2)\n" + 
+				");";
+		
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testOptionalFK() throws Exception {
+		String ddl = "CREATE FOREIGN TABLE G1(g1e1 integer, g1e2 varchar CONSTRAINT PRIMARY KEY(g1e1, g1e2));\n" +
+				"CREATE FOREIGN TABLE G2( g2e1 integer, g2e2 varchar CONSTRAINT PRIMARY KEY(g2e1, g2e2)," +
+				"FOREIGN KEY (g2e1, g2e2) REFERENCES G1)";
+		String expected = "CREATE FOREIGN TABLE G1 (\n" + 
+				"	g1e1 integer,\n" + 
+				"	g1e2 string\n" + 
+				"	CONSTRAINT PRIMARY KEY(g1e1, g1e2)\n" + 
+				");\n" + 
+				"\n" + 
+				"CREATE FOREIGN TABLE G2 (\n" + 
+				"	g2e1 integer,\n" + 
+				"	g2e2 string\n" + 
+				"	CONSTRAINT PRIMARY KEY(g2e1, g2e2), FOREIGN KEY(g2e1, g2e2) REFERENCES G1 \n" + 
+				");";
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testMultipleCommands() throws Exception {
+		String ddl = "CREATE VIEW V1 AS SELECT * FROM PM1.G1 " +
+				"CREATE PROCEDURE FOO(P1 integer) RETURNS (e1 integer, e2 varchar) AS SELECT * FROM PM1.G1;";
+		String expected = "CREATE VIEW V1\n" + 
+				"AS\n" + 
+				"SELECT * FROM PM1.G1;\n" + 
+				"\n" + 
+				"CREATE VIRTUAL PROCEDURE FOO(IN P1 integer) RETURNS (e1 integer, e2 string)\n" + 
+				"AS\n" + 
+				"SELECT * FROM PM1.G1;\n";
+		helpTest(ddl, expected);
+		
+	}	
+	
+	@Test
+	public void testView() throws Exception {
+		String ddl = "CREATE View G1( e1 integer, e2 varchar) OPTIONS (CARDINALITY 12) AS select e1, e2 from foo.bar";
+		String expected = "CREATE VIEW G1 (\n" + 
+				"	e1 integer,\n" + 
+				"	e2 string\n" + 
+				") OPTIONS (CARDINALITY 12)\n" + 
+				"AS\n" + 
+				"SELECT e1, e2 FROM foo.bar;";
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testInsteadOfTrigger() throws Exception {
+		String ddl = 	"CREATE VIEW G1( e1 integer, e2 varchar) AS select * from foo;" +
+						"CREATE TRIGGER ON G1 INSTEAD OF INSERT AS " +
+						"FOR EACH ROW \n" +
+						"BEGIN ATOMIC \n" +
+						"insert into g1 (e1, e2) values (1, 'trig');\n" +
+						"END;";
+
+		String expected = "CREATE VIEW G1 (\n" + 
+				"	e1 integer,\n" + 
+				"	e2 string\n" + 
+				")\n" + 
+				"AS\n" + 
+				"SELECT * FROM foo;\n" + 
+				"\n" + 
+				"CREATE TRIGGER ON G1 INSTEAD OF INSERT AS\n" + 
+				"FOR EACH ROW\n" + 
+				"BEGIN ATOMIC\n" + 
+				"INSERT INTO g1 (e1, e2) VALUES (1, 'trig');\n" + 
+				"END;";
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testSourceProcedure() throws Exception {
+		String ddl = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, p2 varchar, INOUT p3 decimal) " +
+				"RETURNS (r1 varchar, r2 decimal)" +
+				"OPTIONS(RANDOM 'any', UUID 'uuid', NAMEINSOURCE 'nis', ANNOTATION 'desc', UPDATECOUNT '2');";
+		
+		String expected = "CREATE FOREIGN PROCEDURE myProc(OUT p1 boolean, IN p2 string, INOUT p3 bigdecimal) RETURNS (r1 string, r2 bigdecimal)\n" + 
+				"OPTIONS (UUID 'uuid', ANNOTATION 'desc', NAMEINSOURCE 'nis', UPDATECOUNT 2, RANDOM 'any')";
+		helpTest(ddl, expected);		
+	}	
+	
+	@Test
+	public void testPushdownFunctionNoArgs() throws Exception {
+		String ddl = "CREATE FOREIGN FUNCTION SourceFunc() RETURNS integer OPTIONS (UUID 'hello world')";
+		String expected = "CREATE FOREIGN FUNCTION SourceFunc() RETURNS integer\n" + 
+				"OPTIONS (UUID 'hello world');";
+		helpTest(ddl, expected);
+	}	
+	
+	@Test
+	public void testNonPushdownFunction() throws Exception {
+		String ddl = "CREATE FUNCTION SourceFunc(p1 integer, p2 varchar) RETURNS integer OPTIONS (JAVA_CLASS 'foo', JAVA_MEHTOD 'bar')";
+		String expected = "CREATE VIRTUAL FUNCTION SourceFunc(p1 integer, p2 string) RETURNS integer\n" + 
+				"OPTIONS (JAVA_CLASS 'foo', JAVA_MEHTOD 'bar');";
+		helpTest(ddl, expected);
+	}
+
+	private void helpTest(String ddl, String expected) throws ParseException {
+		Schema s = TestDDLParser.helpParse(ddl, "model").getSchema();
+		String metadataDDL = DDLStringVisitor.getDDLString(s, null, null);
+		//System.out.println(metadataDDL);
+		assertEquals(expected, metadataDDL);
+	}	
+}


Property changes on: trunk/engine/src/test/java/org/teiid/query/metadata/TestDDLStringVisitor.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/OperationsConstants.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/OperationsConstants.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/OperationsConstants.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -45,4 +45,6 @@
 	public static final String TIMEOUT_IN_MILLI = "timeout-in-milli";//$NON-NLS-1$
 	public static final String TRANSLATOR_NAME = "translator-name"; //$NON-NLS-1$
 
+	public static final String ENTITY_TYPE = "entity-type"; //$NON-NLS-1$
+	public static final String ENTITY_PATTERN = "entity-pattern"; //$NON-NLS-1$
 }

Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidExtension.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidExtension.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidExtension.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -148,6 +148,7 @@
 		new ExecuteQuery().register(teiidSubsystem);
 		new MarkDataSourceAvailable().register(teiidSubsystem);
 		new ReadRARDescription().register(teiidSubsystem);
+		new GetSchema().register(teiidSubsystem);
 	}
 
 	@Override

Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/TeiidOperationHandler.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -37,11 +37,7 @@
 import java.sql.Clob;
 import java.sql.SQLException;
 import java.sql.SQLXML;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.ResourceBundle;
+import java.util.*;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
@@ -60,9 +56,8 @@
 import org.jboss.jca.common.api.metadata.ra.ResourceAdapter1516;
 import org.jboss.msc.service.ServiceController;
 import org.jboss.msc.service.ServiceName;
-import org.teiid.adminapi.Admin;
-import org.teiid.adminapi.AdminException;
-import org.teiid.adminapi.AdminProcessingException;
+import org.teiid.adminapi.*;
+import org.teiid.adminapi.Admin.SchemaObjectType;
 import org.teiid.adminapi.VDB.ConnectionType;
 import org.teiid.adminapi.impl.CacheStatisticsMetadata;
 import org.teiid.adminapi.impl.RequestMetadata;
@@ -89,6 +84,10 @@
 import org.teiid.dqp.internal.process.SessionAwareCache;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
+import org.teiid.metadata.MetadataStore;
+import org.teiid.metadata.Schema;
+import org.teiid.query.metadata.DDLStringVisitor;
+import org.teiid.query.metadata.TransformationMetadata;
 import org.teiid.query.tempdata.TempTableDataManager;
 
 abstract class TeiidOperationHandler extends BaseOperationHandler<DQPCore> {
@@ -866,6 +865,96 @@
 	}	
 }
 
+class GetSchema extends BaseOperationHandler<VDBRepository>{
+	
+	protected GetSchema() {
+		super("get-schema"); //$NON-NLS-1$
+	}
+	
+	@Override
+	protected VDBRepository getService(OperationContext context, PathAddress pathAddress, ModelNode operation) throws OperationFailedException {
+        ServiceController<?> sc = context.getServiceRegistry(false).getRequiredService(TeiidServiceNames.VDB_REPO);
+        return VDBRepository.class.cast(sc.getValue());	
+	}
+	
+	@Override
+	protected void executeOperation(OperationContext context, VDBRepository repo, ModelNode operation) throws OperationFailedException {
+		if (!operation.hasDefined(OperationsConstants.VDB_NAME)) {
+			throw new OperationFailedException(new ModelNode().set(IntegrationPlugin.Util.getString(OperationsConstants.VDB_NAME+MISSING)));
+		}
+		if (!operation.hasDefined(OperationsConstants.VDB_VERSION)) {
+			throw new OperationFailedException(new ModelNode().set(IntegrationPlugin.Util.getString(OperationsConstants.VDB_VERSION+MISSING)));
+		}
+		if (!operation.hasDefined(OperationsConstants.MODEL_NAME)) {
+			throw new OperationFailedException(new ModelNode().set(IntegrationPlugin.Util.getString(OperationsConstants.MODEL_NAME+MISSING)));
+		}		
+		
+		ModelNode result = context.getResult();
+		String vdbName = operation.get(OperationsConstants.VDB_NAME).asString();
+		int vdbVersion = operation.get(OperationsConstants.VDB_VERSION).asInt();
+		String modelName = operation.get(OperationsConstants.MODEL_NAME).asString();
+
+		VDBMetaData vdb = repo.getVDB(vdbName, vdbVersion);
+		if (vdb == null || (vdb.getStatus() != VDB.Status.ACTIVE)) {
+			throw new OperationFailedException(new ModelNode().set(IntegrationPlugin.Util.getString("no_vdb_found", vdbName, vdbVersion))); //$NON-NLS-1$
+		}
+		
+		EnumSet<SchemaObjectType> schemaTypes = null;
+		if (vdb.getModel(modelName) == null){
+			throw new OperationFailedException(new ModelNode().set(IntegrationPlugin.Util.getString("no_model_found", vdbName, vdbVersion, modelName))); //$NON-NLS-1$
+		}
+		
+		if (operation.hasDefined(OperationsConstants.ENTITY_TYPE)) {
+			String[] types = operation.get(OperationsConstants.ENTITY_TYPE).asString().toUpperCase().split(","); //$NON-NLS-1$
+			if (types.length > 0) {
+				ArrayList<SchemaObjectType> sot = new ArrayList<Admin.SchemaObjectType>();
+				for (int i = 1; i < types.length; i++) {
+					sot.add(SchemaObjectType.valueOf(types[i]));
+				}
+				schemaTypes =  EnumSet.of(SchemaObjectType.valueOf(types[0]), sot.toArray(new SchemaObjectType[sot.size()]));
+			}
+			else {
+				schemaTypes = EnumSet.of(SchemaObjectType.valueOf(types[0]));
+			}
+		}
+		
+		String regEx = null;
+		if (operation.hasDefined(OperationsConstants.ENTITY_PATTERN)) {
+			regEx = operation.get(OperationsConstants.ENTITY_PATTERN).asString();
+		}
+		
+		MetadataStore metadataStore = vdb.getAttachment(TransformationMetadata.class).getMetadataStore();
+		Schema schema = metadataStore.getSchema(modelName);
+		String ddl = DDLStringVisitor.getDDLString(schema, schemaTypes, regEx);
+		result.set(ddl);
+	}
+	
+	protected void describeParameters(ModelNode operationNode, ResourceBundle bundle) {
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_NAME, TYPE).set(ModelType.STRING);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_NAME, REQUIRED).set(true);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_NAME, DESCRIPTION).set(getParameterDescription(bundle, OperationsConstants.VDB_NAME));
+		
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_VERSION, TYPE).set(ModelType.STRING);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_VERSION, REQUIRED).set(true);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.VDB_VERSION, DESCRIPTION).set(getParameterDescription(bundle, OperationsConstants.VDB_VERSION));
+
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.MODEL_NAME, TYPE).set(ModelType.STRING);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.MODEL_NAME, REQUIRED).set(true);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.MODEL_NAME, DESCRIPTION).set(getParameterDescription(bundle, OperationsConstants.MODEL_NAME));
+		
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_TYPE, TYPE).set(ModelType.STRING);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_TYPE, REQUIRED).set(false);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_TYPE, DESCRIPTION).set(getParameterDescription(bundle, OperationsConstants.ENTITY_TYPE));
+
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_PATTERN, TYPE).set(ModelType.STRING);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_PATTERN, REQUIRED).set(false);
+		operationNode.get(REQUEST_PROPERTIES, OperationsConstants.ENTITY_PATTERN, DESCRIPTION).set(getParameterDescription(bundle, OperationsConstants.ENTITY_PATTERN));
+		
+		ModelNode reply = operationNode.get(REPLY_PROPERTIES);
+		reply.get(TYPE).set(ModelType.STRING);		
+	}	
+}
+
 class ListVDBs extends BaseOperationHandler<VDBRepository>{
 	
 	protected ListVDBs() {

Modified: trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
===================================================================
--- trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties	2012-06-22 21:11:13 UTC (rev 4201)
@@ -186,6 +186,8 @@
 TEIID50020= {0} Failed to Pull {1}
 TEIID50022={0} timeout pulling {1}
 TEIID50078=Translator not found {0}
+no_vdb_found=VDB {0}.{1} not found or VDB is not in ACTIVE status
+no_model_found= VDB {0}.{1} does not have model with name {2}.
 
 remove.reply.describe=remove service
 remove.describe=remove service
@@ -215,6 +217,7 @@
 rar-name.missing=Parameter "rar-name" is is required.
 vdb-description.describe=vdb description
 teiid_subsystem.describe=describe the teiid subsystem
+entity-type=Entity Type. Allowed values (ALL, TABLES, PROCEDURES, FUNCTIONS)
 
 # Operation descriptions (alpha layout)
 add-anyauthenticated-role.describe=Mark any authenticated to the datarole
@@ -295,6 +298,14 @@
 get-vdb.vdb-version.describe=vdb version
 get-vdb.reply=vdb
 
+get-schema.describe=Get the VDB with the given name and version
+get-schema.vdb-name.describe=name of the vdb
+get-schema.vdb-version.describe=vdb version
+get-schema.model-name.describe=model name
+get-schema.entity-type.describe=entity type. Allowed values are [ALL, TABLES, PROCEDURES, FUNCTIONS]. If omitted then ALL is assumed.
+get-schema.entity-pattern.describe=allow only entities that match the given regular expression pattern 
+get-schema.reply=schema in the form of DDL
+
 list-requests.describe=List of active requests
 list-requests.reply=list of requests
 

Modified: trunk/jboss-integration/src/test/java/org/teiid/jboss/TestTeiidConfiguration.java
===================================================================
--- trunk/jboss-integration/src/test/java/org/teiid/jboss/TestTeiidConfiguration.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/jboss-integration/src/test/java/org/teiid/jboss/TestTeiidConfiguration.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -202,10 +202,10 @@
         Assert.assertEquals(SUCCESS, result.get(OUTCOME).asString());
         
         List<String> opNames = getList(result);
-        assertEquals(39, opNames.size());
+        assertEquals(40, opNames.size());
 		String[] ops = { "add","add-anyauthenticated-role","add-data-role","assign-datasource",
 				"cache-statistics","cache-types","cancel-request","change-vdb-connection-type",
-				"clear-cache","describe","execute-query","get-plan","get-translator","get-vdb",
+				"clear-cache","describe","execute-query","get-plan","get-schema", "get-translator","get-vdb",
 				"list-long-running-requests","list-requests","list-requests-per-session",
 				"list-requests-per-vdb","list-sessions","list-transactions","list-translators",
 				"list-vdbs","mark-datasource-available","read-attribute",

Modified: trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestDeployment.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestDeployment.java	2012-06-22 14:46:04 UTC (rev 4200)
+++ trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestDeployment.java	2012-06-22 21:11:13 UTC (rev 4201)
@@ -454,4 +454,35 @@
 		conn.close();
 		return execCount;
 	}	
+	
+	@Test
+	public void testDDLExport() throws Exception{
+		String vdbName = "test";
+		String testVDB = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + 
+				"<vdb name=\"test\" version=\"1\">\n" + 
+				"    <property name=\"UseConnectorMetadata\" value=\"cached\" />\n" + 
+				"    <model name=\"loopy\">\n" + 
+				"        <source name=\"loop\" translator-name=\"loopy\" />\n" + 
+				"    </model>\n" + 
+				"</vdb>";
+		
+		Collection<?> vdbs = admin.getVDBs();
+		assertTrue(vdbs.isEmpty());
+		
+		JavaArchive jar = getLoopyArchive();
+		admin.deploy("loopy.jar", jar.as(ZipExporter.class).exportAsInputStream());
+		
+		// normal load
+		admin.deploy("test-vdb.xml", new ByteArrayInputStream(testVDB.getBytes()));
+		AdminUtil.waitForVDBLoad(admin, vdbName, 1, 3);
+		
+		String ddl = admin.getSchema(vdbName, 1, "loopy", null, null);
+
+		String expected = "CREATE FOREIGN TABLE Matadata (\n" + 
+				"	execCount int OPTIONS (SEARCHABLE 'Searchable')\n" + 
+				");";
+		assertEquals(expected, ddl);
+		
+		admin.undeploy("loopy.jar");
+	}	
 }



More information about the teiid-commits mailing list