diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/InfinispanHotRodExecutionFactory.java b/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/InfinispanHotRodExecutionFactory.java index fdee7122bf..d75604fb26 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/InfinispanHotRodExecutionFactory.java +++ b/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/InfinispanHotRodExecutionFactory.java @@ -162,16 +162,6 @@ public boolean supportsNotCriteria() { @Override public MetadataProcessor getMetadataProcessor(){ - // commenting out as the config of protobuf annotations will trigger JDG - // to auto create the protobuf file and marshallers, and therefore, - // the descriptor info will be available for metadatda creation. - // this is important because the correct NIS is assigned to the - // child object/tables so that they are correctly searched via DSL. - - -// if (this.supportsSearchabilityUsingAnnotations()) { -// return new AnnotationMetadataProcessor(true); -// } return new ProtobufMetadataProcessor(); } diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/metadata/ProtobufMetadataProcessor.java b/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/metadata/ProtobufMetadataProcessor.java index ce31c09629..7dcbe6b1e6 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/metadata/ProtobufMetadataProcessor.java +++ b/connectors/infinispan/translator-infinispan-hotrod/src/main/java/org/teiid/translator/infinispan/hotrod/metadata/ProtobufMetadataProcessor.java @@ -115,7 +115,8 @@ public void process(MetadataFactory metadataFactory, ObjectConnection connection private void createRootTable(MetadataFactory mf, Class entity, Descriptor descriptor, String cacheName, InfinispanHotRodConnection conn) throws TranslatorException { String pkField = conn.getPkField(); - boolean updatable = (materialized ? true : (pkField != null ? true : false)); + // the table can only be updateable if it has the pkField defined, even if its materialized) + boolean updatable = (pkField != null ? true : false); rootTable = addTable(mf, entity, updatable, false); if (materialized) { @@ -131,8 +132,7 @@ private void createRootTable(MetadataFactory mf, Class entity, Descriptor des if (updatable) { pkMethod = findMethod(entity.getName(), pkField, conn); if (pkMethod == null) { - throw new TranslatorException(InfinispanPlugin.Util.gs(InfinispanPlugin.Event.TEIID25008, new Object[] {pkField, cacheName, entity.getName()})); - + throw new TranslatorException(InfinispanPlugin.Util.gs(InfinispanPlugin.Event.TEIID25008, new Object[] {pkField, cacheName, entity.getName()})); } } @@ -148,8 +148,7 @@ private void createRootTable(MetadataFactory mf, Class entity, Descriptor des NullType nt = NullType.Nullable; SearchType st = isSearchable(fd); Class returnType = getJavaType( fd,entity, conn); -// String j = fd.getJavaType().name(); - if (fd.getName().equalsIgnoreCase(pkField)) { + if (updatable && fd.getName().equalsIgnoreCase(pkField)) { addKey = true; st = SearchType.Searchable; nt = NullType.No_Nulls; @@ -165,14 +164,15 @@ private void createRootTable(MetadataFactory mf, Class entity, Descriptor des } } // dont make primary key updatable, the object must be deleted and readded in order to change the key - addRootColumn(mf, returnType, getProtobufNativeType(fd), fd.getFullName(), fd.getName(), st, rootTable.getName(), rootTable, true, true, nt); + addRootColumn(mf, returnType, getProtobufNativeType(fd), fd.getFullName(), fd.getName(), st, rootTable.getName(), rootTable, true, updatable, nt); if (materialized) { addRootColumn(mf, returnType, getProtobufNativeType(fd), fd.getFullName(), fd.getName(), st, stagingTable.getName(), stagingTable, true, true, nt); } } - - if (pkMethod != null) { + + + if (updatable) { @SuppressWarnings("null") String pkName = "PK_" + pkField.toUpperCase(); //$NON-NLS-1$ ArrayList x = new ArrayList(1) ; @@ -181,18 +181,17 @@ private void createRootTable(MetadataFactory mf, Class entity, Descriptor des if (materialized) { mf.addPrimaryKey(pkName, x , stagingTable); } - } - - if (!addKey) { - addRootColumn(mf, pkMethod.getReturnType(), pkMethod.getReturnType(), pkField, pkField, SearchType.Searchable, rootTable.getName(), rootTable, true, true, NullType.No_Nulls); - } - - for (String key : descriptorMap.keySet()) { - FieldDescriptor fd = descriptorMap.get(key); - Descriptor d = fd.getMessageType(); - createInnerTable(mf, d, key, rootTable, pkMethod, conn); + + // if materialized, child objects (relationships) are not supported, so no need to create them + if (!materialized && updatable) { + for (String key : descriptorMap.keySet()) { + FieldDescriptor fd = descriptorMap.get(key); + Descriptor d = fd.getMessageType(); + createInnerTable(mf, d, key, rootTable, pkMethod, conn); + + } } } diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/main/resources/org/teiid/translator/infinispan/hotrod/i18n.properties b/connectors/infinispan/translator-infinispan-hotrod/src/main/resources/org/teiid/translator/infinispan/hotrod/i18n.properties index d48b040361..438a3a2480 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/main/resources/org/teiid/translator/infinispan/hotrod/i18n.properties +++ b/connectors/infinispan/translator-infinispan-hotrod/src/main/resources/org/teiid/translator/infinispan/hotrod/i18n.properties @@ -28,7 +28,7 @@ TEIID25004=Unable to perform {0}, no Primary or Foreign Key defined for table {1 TEIID25005=Table {0} has defined a container class of type Maps, which is not currently supported TEIID25006=Updating primary key column {0} in table {1} is not supported, use delete and insert. TEIID25007=Updates are disabled, no Primary key defined for cache {0} -TEIID25008=Primary Key {0} defined for cache {1} does not match a method on class {2} +TEIID25008=Primary key field {0} defined for cache {1} does not match a method on class {2} TEIID25009=Unable to insert duplicate into table {0} with key value {1} TEIID25010=The alias cache '{0}' doesnt exist in the Remote Cache container TEIID25011=The StagingCacheName and AliasCacheName must both be configured to do materialization diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheConnection.java b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheConnection.java index 002280f282..c3c9c38e4d 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheConnection.java +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheConnection.java @@ -38,17 +38,14 @@ */ public class PersonCacheConnection extends TestInfinispanHotRodConnection { - public static InfinispanHotRodConnection createConnection(RemoteCache map, boolean useKeyClassType, Version version) { - CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); - - PersonCacheConnection conn = new PersonCacheConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy, useKeyClassType); - conn.setVersion(version); - conn.setConfiguredUsingAnnotations(true); - return conn; - } - - public static InfinispanHotRodConnection createConnection(RemoteCache map, final String keyField, boolean useKeyClassType, Version version) { - CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); + public static InfinispanHotRodConnection createConnection(RemoteCache map, final String keyField, boolean useKeyClassType, boolean staging, Version version) { + CacheNameProxy proxy = null; + + if (staging) { + proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME, "ST_" + PersonCacheSource.PERSON_CACHE_NAME, "aliasCacheName"); + } else { + proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); + } PersonCacheConnection conn = new PersonCacheConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy, useKeyClassType) { @@ -62,6 +59,32 @@ public void setPkField(String keyfield) { return conn; } + public static InfinispanHotRodConnection createConnection(RemoteCache map, boolean useKeyClassType, Version version) { + return createConnection(map, "id", useKeyClassType, version); +// CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); +// +// PersonCacheConnection conn = new PersonCacheConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy, useKeyClassType); +// conn.setVersion(version); +// conn.setConfiguredUsingAnnotations(true); +// return conn; + } + + public static InfinispanHotRodConnection createConnection(RemoteCache map, final String keyField, boolean useKeyClassType, Version version) { + return createConnection(map, keyField, useKeyClassType, false, version); +// CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); +// PersonCacheConnection conn = new PersonCacheConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy, useKeyClassType) { +// +// @Override +// public void setPkField(String keyfield) { +// super.setPkField(keyField); +// } +// }; +// conn.setVersion(version); +// conn.setConfiguredUsingAnnotations(true); +// return conn; + + } + /** * @param map * @param registry diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheSource.java b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheSource.java index 48fb86a9c9..9d1632e613 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheSource.java +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/jboss/as/quickstarts/datagrid/hotrod/query/domain/PersonCacheSource.java @@ -49,6 +49,7 @@ import org.infinispan.query.dsl.Query; import org.teiid.translator.infinispan.hotrod.InfinispanHotRodConnection; import org.teiid.translator.object.ClassRegistry; +import org.teiid.translator.object.ObjectConnection; import org.teiid.util.Version; /** @@ -96,17 +97,23 @@ public class PersonCacheSource implements RemoteCache{ public static InfinispanHotRodConnection createConnection(final boolean useKeyClass) { - final RemoteCache objects = PersonCacheSource.loadCache(); - - return PersonCacheConnection.createConnection(objects, useKeyClass, null); - + return createConnection(useKeyClass, null); } public static InfinispanHotRodConnection createConnection(final boolean useKeyClass, Version version) { + return createConnection("id", useKeyClass, version); + } + + public static InfinispanHotRodConnection createConnection(final String keyField, final boolean useKeyClass, Version version) { final RemoteCache objects = PersonCacheSource.loadCache(); - return PersonCacheConnection.createConnection(objects, useKeyClass, version); + return PersonCacheConnection.createConnection(objects, keyField, useKeyClass, version); + + } + public static ObjectConnection createConnection(final boolean useKeyClass, boolean staging, Version version) { + final RemoteCache objects = PersonCacheSource.loadCache(); + return PersonCacheConnection.createConnection(objects, "id", useKeyClass, staging, version); } public static void loadCache(Map cache) { diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/teiid/translator/infinispan/hotrod/metadata/TestProtobufMetadataProcessor.java b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/teiid/translator/infinispan/hotrod/metadata/TestProtobufMetadataProcessor.java index 25bebe020c..7e182455d5 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/teiid/translator/infinispan/hotrod/metadata/TestProtobufMetadataProcessor.java +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/java/org/teiid/translator/infinispan/hotrod/metadata/TestProtobufMetadataProcessor.java @@ -17,6 +17,8 @@ import org.teiid.query.metadata.SystemMetadata; import org.teiid.translator.infinispan.hotrod.InfinispanHotRodConnection; import org.teiid.translator.infinispan.hotrod.InfinispanHotRodExecutionFactory; +import org.teiid.translator.object.ObjectConnection; +import org.teiid.translator.object.testdata.trades.TradesCacheSource; @SuppressWarnings("nls") public class TestProtobufMetadataProcessor { @@ -47,7 +49,7 @@ public void testPersonMetadata() throws Exception { String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); - assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")), metadataDDL); + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")).trim(), metadataDDL.trim()); } @@ -58,14 +60,14 @@ public void testPersonMetadataUpperCaseKeyField() throws Exception { SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); - InfinispanHotRodConnection conn = PersonCacheConnection.createConnection(PersonCacheSource.loadCache(), "ID", false, null); - + InfinispanHotRodConnection conn = PersonCacheSource.createConnection("ID", false, null); + TRANSLATOR.getMetadataProcessor().process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); - assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")), metadataDDL); + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")).trim(), metadataDDL.trim()); } @Test @@ -75,14 +77,14 @@ public void testPersonMetadataMixedCaseKeyField() throws Exception { SystemMetadata.getInstance().getRuntimeTypeMap(), new Properties(), null); - InfinispanHotRodConnection conn = PersonCacheConnection.createConnection(PersonCacheSource.loadCache(), "Id", false, null); - + InfinispanHotRodConnection conn = PersonCacheSource.createConnection("Id", false, null); + TRANSLATOR.getMetadataProcessor().process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); - assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")), metadataDDL); + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadata.ddl")).trim(), metadataDDL.trim()); } @Test @@ -99,8 +101,44 @@ public void testAllTypesMetadata() throws Exception { String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); - assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("allTypesMetadata.ddl")), metadataDDL ); + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("allTypesMetadata.ddl")).trim(), metadataDDL.trim() ); + + } + + @Test + public void testMatPersonMetadata() throws Exception { + ObjectConnection conn = PersonCacheSource.createConnection(true, true, null); + + MetadataFactory mf = new MetadataFactory("vdb", 1, "objectvdb", + SystemMetadata.getInstance().getRuntimeTypeMap(), + new Properties(), null); + + TRANSLATOR.getMetadataProcessor().process(mf, conn); + + String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), + null, null); + + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMatMetadata.ddl")).trim(), metadataDDL.trim() ); + + } + + @Test + public void testPersonMetadataNoPKKey() throws Exception { + ObjectConnection conn = PersonCacheSource.createConnection(null, false, null); + + MetadataFactory mf = new MetadataFactory("vdb", 1, "objectvdb", + SystemMetadata.getInstance().getRuntimeTypeMap(), + new Properties(), null); + + + TRANSLATOR.getMetadataProcessor().process(mf, conn); + + String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), + null, null); + + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personNoKey.ddl")).trim(), metadataDDL.trim() ); } + } diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMatMetadata.ddl b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMatMetadata.ddl new file mode 100644 index 0000000000..5c82617ce9 --- /dev/null +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMatMetadata.ddl @@ -0,0 +1,15 @@ +SET NAMESPACE 'http://www.teiid.org/translator/object/2016' AS n0; + +CREATE FOREIGN TABLE Person ( + name string NOT NULL OPTIONS (NAMEINSOURCE 'name', SEARCHABLE 'Searchable', NATIVE_TYPE 'java.lang.String'), + id integer NOT NULL OPTIONS (NAMEINSOURCE 'id', SEARCHABLE 'Searchable', NATIVE_TYPE 'int'), + email string OPTIONS (NAMEINSOURCE 'email', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.String'), + CONSTRAINT PK_ID PRIMARY KEY(id) +) OPTIONS (UPDATABLE TRUE); + +CREATE FOREIGN TABLE ST_Person ( + name string NOT NULL OPTIONS (NAMEINSOURCE 'name', SEARCHABLE 'Searchable', NATIVE_TYPE 'java.lang.String'), + id integer NOT NULL OPTIONS (NAMEINSOURCE 'id', SEARCHABLE 'Searchable', NATIVE_TYPE 'int'), + email string OPTIONS (NAMEINSOURCE 'email', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.String'), + CONSTRAINT PK_ID PRIMARY KEY(id) +) OPTIONS (UPDATABLE TRUE, "n0:primary_table" 'objectvdb.Person'); diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMetadata.ddl b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMetadata.ddl index e8bfa57d0d..b072dbe207 100644 --- a/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMetadata.ddl +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personMetadata.ddl @@ -18,4 +18,4 @@ CREATE FOREIGN TABLE PhoneNumber ( type string OPTIONS (NAMEINSOURCE 'phone.type', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.Enum'), id integer NOT NULL OPTIONS (NAMEINSOURCE 'id', SELECTABLE FALSE, SEARCHABLE 'Searchable', NATIVE_TYPE 'int'), CONSTRAINT FK_PERSON FOREIGN KEY(id) REFERENCES Person (id) OPTIONS (NAMEINSOURCE 'phones') -) OPTIONS (UPDATABLE TRUE); \ No newline at end of file +) OPTIONS (UPDATABLE TRUE); diff --git a/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personNoKey.ddl b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personNoKey.ddl new file mode 100644 index 0000000000..963d0e8e69 --- /dev/null +++ b/connectors/infinispan/translator-infinispan-hotrod/src/test/resources/personNoKey.ddl @@ -0,0 +1,6 @@ +CREATE FOREIGN TABLE Person ( + name string NOT NULL OPTIONS (NAMEINSOURCE 'name', SEARCHABLE 'Searchable', NATIVE_TYPE 'java.lang.String'), + id integer NOT NULL OPTIONS (NAMEINSOURCE 'id', SEARCHABLE 'Searchable', NATIVE_TYPE 'int'), + email string OPTIONS (NAMEINSOURCE 'email', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.String') +); + \ No newline at end of file diff --git a/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/ObjectPlugin.java b/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/ObjectPlugin.java index 8807b50d0d..5a3eeec7ee 100644 --- a/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/ObjectPlugin.java +++ b/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/ObjectPlugin.java @@ -56,6 +56,7 @@ public static enum Event implements BundleUtil.Event{ TEIID21014, TEIID21015, TEIID21016, + TEIID21017, TEIID21302, } } diff --git a/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/metadata/JavaBeanMetadataProcessor.java b/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/metadata/JavaBeanMetadataProcessor.java index a3af23cdf2..dbfcbe4b6f 100644 --- a/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/metadata/JavaBeanMetadataProcessor.java +++ b/connectors/infinispan/translator-object/src/main/java/org/teiid/translator/object/metadata/JavaBeanMetadataProcessor.java @@ -25,6 +25,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -41,7 +42,9 @@ import org.teiid.metadata.Table; import org.teiid.translator.MetadataProcessor; import org.teiid.translator.TranslatorException; +import org.teiid.translator.TranslatorProperty; import org.teiid.translator.TypeFacility; +import org.teiid.translator.TranslatorProperty.PropertyType; import org.teiid.translator.object.ClassRegistry; import org.teiid.translator.object.ObjectConnection; import org.teiid.translator.object.ObjectPlugin; @@ -67,12 +70,22 @@ public class JavaBeanMetadataProcessor implements MetadataProcessor entity, ObjectConnect } String pkField = conn.getPkField(); - boolean updatable = determineUpdatable(conn, pkField, entity.getSimpleName(), methods); + // the table can only be updateable if it has the pkField defined, even if its materialized) + boolean updatable = (pkField != null ? true : false); + pkMethod = null; + if (updatable) { + pkMethod = findMethod(entity.getName(), pkField, conn); + if (pkMethod == null) { + throw new TranslatorException(ObjectPlugin.Util.gs(ObjectPlugin.Event.TEIID21017, new Object[] {pkField, conn.getCacheName(), entity.getName()})); + } + } + rootTable = createTable(mf, entity, updatable, false); if (materializedSource) { stagingTable = createTable(mf, entity, true, true); } - if (!materializedSource) { + if (classObjectColumn && !materializedSource) { String columnName = rootTable.getName() + OBJECT_COL_SUFFIX; addColumn(mf, entity, columnName, "this", SearchType.Unsearchable, rootTable, false, NullType.Nullable, false); //$NON-NLS-1$ } - String colname = getNameFromMethodName(pkMethod.getName()); - if (pkMethod != null) { - addColumn(mf, pkMethod.getReturnType(), pkField, pkField, SearchType.Searchable, this.rootTable, true, NullType.No_Nulls, updatable); - - if (materializedSource) { + if (updatable) { + // add the primary key field information; column and primary key + addColumn(mf, pkMethod.getReturnType(), pkField, pkField, SearchType.Searchable, this.rootTable, true, NullType.No_Nulls, updatable); + + if (materializedSource) { addColumn(mf, pkMethod.getReturnType(), pkField, pkField, SearchType.Searchable, stagingTable, true, NullType.No_Nulls, true); - } - } else { - // add a column so the PKey can be created, but make it not selectable - addColumn(mf, java.lang.String.class, pkField, pkField, SearchType.Searchable, this.rootTable, false, NullType.Unknown, updatable); + } + + String colname = getNameFromMethodName(pkMethod.getName()); + addPrimaryKey(mf, colname, rootTable); + + if (materializedSource) { - addColumn(mf, java.lang.String.class, pkField, pkField, SearchType.Searchable, stagingTable, false, NullType.Unknown, true); + addPrimaryKey(mf, colname , stagingTable); } - } - - addPrimaryKey(mf, colname, rootTable); - - if (materializedSource) { - addPrimaryKey(mf, colname , stagingTable); } + - addTableContents(mf, rootTable, entity, colname, conn, false, updatable, methods, writeMethods); + addTableContents(mf, rootTable, entity, pkField, conn, false, updatable, methods, writeMethods); if (materializedSource) { - addTableContents(mf, stagingTable, entity, colname, conn, true, updatable, methods, writeMethods); + addTableContents(mf, stagingTable, entity, pkField, conn, true, updatable, methods, writeMethods); } } @@ -161,19 +180,6 @@ private void addPrimaryKey(MetadataFactory mf, String pkField, Table t ) { } - private boolean determineUpdatable(ObjectConnection conn, String pkField, String entityName, Map methods) { - - this.pkMethod = null; - if (pkField != null) { - pkMethod = methods.get(pkField); - } else { - // warn if no pk is defined - LogManager.logWarning(LogConstants.CTX_CONNECTOR, ObjectPlugin.Util.gs(ObjectPlugin.Event.TEIID21000, entityName)); - } - - return (materializedSource ? true : (pkField != null ? true : false)); - } - private Table createTable(MetadataFactory mf, Class entity, boolean updatable, boolean staging) { String tableName = getTableName(entity); @@ -215,8 +221,11 @@ private void addTableContents(MetadataFactory mf, Table table, Class entity, if (regClasses.contains(entry.getValue().getReturnType())) { - Table childTable = createChildTable(mf, entry.getValue().getReturnType(), pkField, updatable, conn); - createRelationShip(mf, childTable, (Method) o, this.rootTable, this.pkMethod, conn); + // only if pkfield is defined can children be defined + if (pkField != null) { + Table childTable = createChildTable(mf, entry.getValue().getReturnType(), pkField, updatable, conn); + createRelationShip(mf, childTable, (Method) o, this.rootTable, this.pkMethod, conn); + } } else { continue; @@ -262,7 +271,6 @@ private void addTableContents(MetadataFactory mf, Table table, Class entity, } } - // getNameFromMethodName(m.getName()) addColumn(mf, m.getReturnType(), entry.getValue(), entry.getValue(), st, table, true, nt, columnUpdatable); } } @@ -430,5 +438,27 @@ private void createRelationShip(MetadataFactory mf, Table childTable, Method par } } + + private static Method findMethod(String className, String methodName, ObjectConnection conn) throws TranslatorException { + Map mapMethods = conn.getClassRegistry().getReadClassMethods(className); + + + Method m = ClassRegistry.findMethod(mapMethods, methodName, className); + + if (m != null) return m; + + // because the class 'methods' contains 2 different references + // get'Name' and 'Name', this will look for the 'Name' version + for (Iterator it=mapMethods.keySet().iterator(); it.hasNext();) { + String mName = it.next(); + if (mName.toLowerCase().startsWith(methodName.toLowerCase()) ) { + m = mapMethods.get(mName); + return m; + } + } + throw new TranslatorException("Program Error: unable to find method " + methodName + " on class " + className); + + } + } diff --git a/connectors/infinispan/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties b/connectors/infinispan/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties index ff1599643f..7aa736e1cf 100644 --- a/connectors/infinispan/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties +++ b/connectors/infinispan/translator-object/src/main/resources/org/teiid/translator/object/i18n.properties @@ -41,7 +41,7 @@ TEIID21013=ObjectUpdateExecution: Warning - The object does not exist when tryin TEIID21014=ObjectUpdateException: Delete ALL is not supported, must pass in criteria for what is to be deleted TEIID21015=Unable to insert child object, key {0} for root object {1} couldn't be found TEIID21016=ObjectUpdateException: Invalid argument value "{0}" when executing (method) {1} on (api) {2} of (argType) {3} - +TEIID21017=Primary key field {0} defined for cache {1} does not match a method on class {2} TEIID21301=Materialization Life Cycle Issue: invalid arguments on native query "{0}", should use format: "{1}" TEIID21302=Materialization Life Cycle Issue: invalid native query "{0}", must follow either format: "{1}" diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java index ed3332b5e1..0a3c5ec459 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/TestObjectExecutionFactory.java @@ -105,14 +105,12 @@ protected ObjectExecutionFactory createFactory() { assertNotNull(physicalTable); assertTrue(physicalTable.isPhysical()); assertTrue(!physicalTable.isVirtual()); - assertEquals(6, physicalTable.getColumns().size()); + assertEquals(5, physicalTable.getColumns().size()); //this - assertEquals("object", physicalTable.getColumns().get(0).getRuntimeType()); - //trade id key - assertEquals("long", physicalTable.getColumns().get(1).getRuntimeType()); - assertEquals(NullType.No_Nulls, physicalTable.getColumns().get(1).getNullType()); + assertEquals("long", physicalTable.getColumns().get(0).getRuntimeType()); + assertEquals(NullType.No_Nulls, physicalTable.getColumns().get(0).getNullType()); //name - assertEquals("object", physicalTable.getColumns().get(2).getRuntimeType()); + assertEquals("object", physicalTable.getColumns().get(1).getRuntimeType()); assertEquals(1, physicalTable.getAllKeys().size()); } diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestAnnotationMetadataProcessor.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestAnnotationMetadataProcessor.java index 0f1f2d557c..0ed2268b55 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestAnnotationMetadataProcessor.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestAnnotationMetadataProcessor.java @@ -38,6 +38,7 @@ public void testTradesMetadata() throws Exception { JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), @@ -70,7 +71,9 @@ public void testPersonMetadataWithNoObjectColumn() throws Exception { TRANSLATOR.initCapabilities(conn); TRANSLATOR.start(); - TRANSLATOR.getMetadataProcessor().process(mf, conn); + JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); + mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestPersonMetadataProcessor.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestPersonMetadataProcessor.java index 75bf71b906..3023a52b08 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestPersonMetadataProcessor.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestPersonMetadataProcessor.java @@ -6,6 +6,8 @@ import org.junit.Before; import org.junit.Test; +import org.teiid.core.util.ObjectConverterUtil; +import org.teiid.core.util.UnitTestUtil; import org.teiid.metadata.MetadataFactory; import org.teiid.query.metadata.DDLStringVisitor; import org.teiid.query.metadata.SystemMetadata; @@ -37,7 +39,9 @@ public void testPersonMetadata() throws Exception { TRANSLATOR.initCapabilities(conn); TRANSLATOR.start(); - TRANSLATOR.getMetadataProcessor().process(mf, conn); + JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); + mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); @@ -54,6 +58,26 @@ public void testPersonMetadata() throws Exception { } + @Test + public void testPersonMetadataNoKey() throws Exception { + + MetadataFactory mf = new MetadataFactory("vdb", 1, "objectvdb", + SystemMetadata.getInstance().getRuntimeTypeMap(), + new Properties(), null); + + ObjectConnection conn = PersonCacheSource.createConnection(null); + + TRANSLATOR.initCapabilities(conn); + TRANSLATOR.start(); + + TRANSLATOR.getMetadataProcessor().process(mf, conn); + + String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), + null, null); + + assertEquals(ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("personMetadataNoKey.ddl")).trim(), metadataDDL.trim() ); + + } } diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestTradesMetadataProcessor.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestTradesMetadataProcessor.java index 2abfd66d89..0cb4cddba0 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestTradesMetadataProcessor.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/metadata/TestTradesMetadataProcessor.java @@ -39,7 +39,9 @@ public void testTradeChildMetadata() throws Exception { TRANSLATOR.initCapabilities(conn); TRANSLATOR.start(); - TRANSLATOR.getMetadataProcessor().process(mf, conn); + JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); + mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); @@ -60,7 +62,9 @@ public void testTradeMetadataFromVDB() throws Exception { TRANSLATOR.initCapabilities(conn); TRANSLATOR.start(); - TRANSLATOR.getMetadataProcessor().process(mf, conn); + JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); + mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); @@ -81,7 +85,9 @@ public void testMatTradeMetadataFromVDB() throws Exception { TRANSLATOR.initCapabilities(conn); TRANSLATOR.start(); - TRANSLATOR.getMetadataProcessor().process(mf, conn); + JavaBeanMetadataProcessor mp = (JavaBeanMetadataProcessor) TRANSLATOR.getMetadataProcessor(); + mp.setClassObjectColumn(true); + mp.process(mf, conn); String metadataDDL = DDLStringVisitor.getDDLString(mf.getSchema(), null, null); diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonCacheSource.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonCacheSource.java index 349e3d433a..0faf76a239 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonCacheSource.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonCacheSource.java @@ -78,6 +78,14 @@ public static ObjectConnection createConnection() { } + public static ObjectConnection createConnection(String pkKeyField) { + final Map objects = PersonCacheSource.loadCache(); + + ObjectConnection toc = PersonObjectConnection.createConnection(objects, pkKeyField); + return toc; + + } + public static void loadCache(Map cache) { PhoneType[] types = new PhoneType[] {PhoneType.HOME, PhoneType.MOBILE, PhoneType.WORK}; int t = 0; diff --git a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonObjectConnection.java b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonObjectConnection.java index 7ce7cf0568..95b4d9cb98 100644 --- a/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonObjectConnection.java +++ b/connectors/infinispan/translator-object/src/test/java/org/teiid/translator/object/testdata/person/PersonObjectConnection.java @@ -11,7 +11,22 @@ public class PersonObjectConnection extends SimpleMapCacheConnection { public static ObjectConnection createConnection(Map map) { CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); - return new PersonObjectConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy); + ObjectConnection conn = new PersonObjectConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy); + + return conn; + } + + public static ObjectConnection createConnection(Map map, final String keyField) { + CacheNameProxy proxy = new CacheNameProxy(PersonCacheSource.PERSON_CACHE_NAME); + ObjectConnection conn = new PersonObjectConnection(map, PersonCacheSource.CLASS_REGISTRY, proxy){ + + @Override + public void setPkField(String keyfield) { + super.setPkField(keyField); + } + }; + + return conn; } public static ObjectConnection createConnection(Map cache, Map stagecache, Map aliascache, CacheNameProxy proxy) { diff --git a/connectors/infinispan/translator-object/src/test/resources/personMetadataNoKey.ddl b/connectors/infinispan/translator-object/src/test/resources/personMetadataNoKey.ddl new file mode 100644 index 0000000000..dfdecb357c --- /dev/null +++ b/connectors/infinispan/translator-object/src/test/resources/personMetadataNoKey.ddl @@ -0,0 +1,5 @@ + CREATE FOREIGN TABLE Person ( + email string OPTIONS (NAMEINSOURCE 'email', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.String'), + id integer OPTIONS (NAMEINSOURCE 'id', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'int'), + name string OPTIONS (NAMEINSOURCE 'name', SEARCHABLE 'Unsearchable', NATIVE_TYPE 'java.lang.String') +);